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

Subversion Repositories z3

[/] [z3/] [trunk/] [z3.vl] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 charcole
module boss(clk, adcDout, reset, data, waddress, we, pe, romCS, ramCS, led0, led1, led2, lcdCS, lcdRS, lcdReset, nadcCS, a17, a18);
2
 
3
input clk;
4
input adcDout;
5
input reset;
6
 
7
inout [7:0] data;
8
 
9
output [16:0] waddress;
10
output we;
11
output pe;
12
output romCS;
13
output ramCS;
14
output led0;
15
output led1;
16
output led2;
17
output lcdCS;
18
output lcdRS;
19
output lcdReset;
20
output nadcCS;
21
output a17;
22
output a18;
23
 
24
reg [16:0] address;
25
reg [7:0] dataOut;
26
reg printEnable;
27
reg writeEnable;
28
reg rlcdRS;
29
reg rlcdReset;
30
reg adcCS;
31
reg a17;
32
reg a18;
33
 
34
wire [16:0] waddress;
35
wire we;
36
wire pe;
37
wire romCS;
38
wire ramCS;
39
wire led0;
40
wire led1;
41
wire led2;
42
wire lcdCS;
43
wire lcdRS;
44
wire lcdReset;
45
wire nadcCS;
46
 
47
 
48
//`define HARDWARE_PRINT
49
//`define REAL_HARDWARE
50
 
51
`define CALLBACK_BASE           'h1E58B
52
`define INIT_CALLBACK           'h0
53
`define PRINT_CALLBACK          'h1
54
`define PRINTCHAR_CALLBACK      'h2
55
`define PRINTNUM_CALLBACK       'h3
56
`define READ_CALLBACK           'h4
57
`define STATUS_CALLBACK         'h5
58
`define QUIT_CALLBACK           'h6
59
`define EXCEPTION_CALLBACK      'h7
60
 
61
`define OPER_LARGE 2'b00
62
`define OPER_SMALL 2'b01
63
`define OPER_VARI  2'b10
64
`define OPER_OMIT  2'b11
65
 
66
`define STATE_RESET             0
67
`define STATE_FETCH_OP          1
68
`define STATE_READ_TYPES        2
69
`define STATE_READ_OPERS        3
70
`define STATE_READ_INDIRECT     4
71
`define STATE_READ_STORE        5
72
`define STATE_READ_BRANCH       6
73
`define STATE_DO_OP                     7
74
`define STATE_READ_FUNCTION     8
75
`define STATE_CALL_FUNCTION     9
76
`define STATE_RET_FUNCTION      10
77
`define STATE_STORE_REGISTER 11
78
`define STATE_PRINT                     12
79
`define STATE_DIVIDE            13
80
`define STATE_HALT                      14
81
`define STATE_PRINT_CHAR        15
82
 
83
`define OP_0    2'b00
84
`define OP_1    2'b01
85
`define OP_2    2'b10
86
`define OP_VAR  2'b11
87
 
88
`define OP0_RTRUE       'h0
89
`define OP0_RFALSE      'h1
90
`define OP0_PRINT       'h2
91
`define OP0_PRINTRET 'h3
92
`define OP0_NOP         'h4
93
`define OP0_SAVE        'h5
94
`define OP0_RESTORE     'h6
95
`define OP0_RESTART     'h7
96
`define OP0_RETPOP      'h8
97
`define OP0_POP         'h9
98
`define OP0_QUIT        'hA
99
`define OP0_NEWLINE     'hB
100
`define OP0_SHOWSTATUS  'hC
101
`define OP0_VERIFY      'hD
102
`define OP0_DYNAMIC     'hF
103
 
104
`define OP1_JZ          'h0
105
`define OP1_GETSIBLING 'h1
106
`define OP1_GETCHILD 'h2
107
`define OP1_GETPARENT 'h3
108
`define OP1_GETPROPLEN 'h4
109
`define OP1_INC         'h5
110
`define OP1_DEC         'h6
111
`define OP1_PRINTADDR 'h7
112
`define OP1_SWITCHBANK 'h8
113
`define OP1_REMOVEOBJ 'h9
114
`define OP1_PRINTOBJ 'hA
115
`define OP1_RET         'hB
116
`define OP1_JUMP        'hC
117
`define OP1_PRINTPADDR 'hD
118
`define OP1_LOAD 'hE
119
`define OP1_NOT 'hF
120
 
121
`define OP2_JE          'h1
122
`define OP2_JL          'h2
123
`define OP2_JG          'h3
124
`define OP2_DEC_CHK     'h4
125
`define OP2_INC_CHK     'h5
126
`define OP2_JIN         'h6
127
`define OP2_TEST        'h7
128
`define OP2_OR          'h8
129
`define OP2_AND         'h9
130
`define OP2_TESTATTR 'hA
131
`define OP2_SETATTR 'hB
132
`define OP2_CLEARATTR 'hC
133
`define OP2_STORE       'hD
134
`define OP2_INSERTOBJ 'hE
135
`define OP2_LOADW       'hF
136
`define OP2_LOADB       'h10
137
`define OP2_GETPROP     'h11
138
`define OP2_GETPROPADDR 'h12
139
`define OP2_GETNEXTPROP 'h13
140
`define OP2_ADD         'h14
141
`define OP2_SUB         'h15
142
`define OP2_MUL         'h16
143
`define OP2_DIV         'h17
144
`define OP2_MOD         'h18
145
`define OP2_WRITEREG 'h1E
146
 
147
`define OPVAR_CALL   'h0
148
`define OPVAR_STOREW 'h1
149
`define OPVAR_STOREB 'h2
150
`define OPVAR_PUTPROP 'h3
151
`define OPVAR_SREAD  'h4
152
`define OPVAR_PRINTCHAR 'h5
153
`define OPVAR_PRINTNUM 'h6
154
`define OPVAR_RANDOM 'h7
155
`define OPVAR_PUSH 'h8
156
`define OPVAR_PULL 'h9
157
`define OPVAR_GETTOUCH 'h1E
158
`define OPVAR_BLIT1     'h1F
159
 
160
`define PRINTEFFECT_FETCH               0
161
`define PRINTEFFECT_FETCHAFTER  1
162
`define PRINTEFFECT_RET1                2
163
`define PRINTEFFECT_ABBREVRET   3
164
 
165
reg forceStaticRead;
166
reg forceDynamicRead;
167
 
168
reg [3:0] state;
169
reg [3:0] phase;
170
 
171
reg [16:0] pc;
172
reg [16:0] curPC;
173
reg [15:0] globalsAddress;
174
reg [15:0] objectTable;
175
 
176
reg readHigh;
177
 
178
reg [4:0] op;
179
reg [1:0] operNum;
180
reg [1:0] operTypes [4:0];
181
reg [15:0] operand [3:0];
182
reg [2:0] operandIdx;
183
reg [13:0] branch;
184
reg [7:0] store;
185
reg negate;
186
 
187
reg delayedBranch;
188
reg divideAddOne;
189
 
190
reg [15:0] returnValue;
191
 
192
reg [6:0] opsToRead;
193
reg [6:0] currentLocal;
194
reg [16:0] csStack;
195
reg [15:0] stackAddress;
196
 
197
reg [16:0] temp;
198
reg [15:0] random;
199
 
200
reg [1:0] alphabet;
201
reg [1:0] long;
202
reg nextLoadIsDynamic;
203
reg lastWriteWasDraw;
204
 
205
reg adcClk;
206
reg adcDin;
207
 
208
reg [7:0] cachedReg;
209
reg [15:0] cachedValue;
210
 
211
// xp<=adcConfig[0]?0:'bZ;
212
// yp<=adcConfig[1]?1:'bZ;
213
// xm<=adcConfig[2]?1:'bZ;
214
// ym<=adcConfig[3]?0:'bZ;
215
// XP dataOut[6]
216
// XM lcsRS
217
// YP dataOut[7]
218
// YM lcdWR
219
 
220
initial
221
begin
222
        state=`STATE_RESET;
223
        forceDynamicRead=0;
224
        forceStaticRead=0;
225
        writeEnable=0;
226
        printEnable=0;
227
        phase=0;
228
        readHigh=0;
229
        nextLoadIsDynamic=0;
230
        adcCS=0;
231
        a17=0;
232
        a18=0;
233
        cachedReg=0;
234
        cachedValue=0;
235
        lastWriteWasDraw=0;
236
end
237
 
238
assign waddress[16:2] = address[16:2];
239
assign waddress[0] = adcCS?adcClk:address[0];
240
assign waddress[1] = adcCS?adcDin:address[1];
241
assign data[5:0] = (writeEnable || printEnable)?dataOut[5:0]:6'bZ;
242
assign data[6] = (writeEnable || printEnable)?dataOut[6]:((adcCS && operand[0][0])?0:'bZ);
243
assign data[7] = (writeEnable || printEnable)?dataOut[7]:((adcCS && operand[0][1])?1:'bZ);
244
assign romCS = !(!adcCS && !printEnable && !writeEnable && !forceDynamicRead && (forceStaticRead || address[16]==1));
245
assign ramCS = !(!adcCS && !printEnable && (writeEnable || forceDynamicRead || (!forceStaticRead && address[16]==0)));
246
assign pe = adcCS?(operand[0][3]?0:'bZ):(!printEnable || !clk);
247
assign we = !writeEnable;
248
assign led0 = !address[12];
249
assign led1 = !address[13];
250
assign led2 = !address[14];
251
assign lcdCS = !printEnable || !clk;
252
assign lcdRS = adcCS?(operand[0][2]?1:'bZ):rlcdRS;
253
assign lcdReset = rlcdReset;
254
assign nadcCS = !adcCS;
255
 
256
task StoreB;
257
        begin
258
                if (phase==0) begin
259
                        cachedReg<=15; nextLoadIsDynamic<=0; address<=operand[0]+operand[1]; writeEnable<=1; dataOut<=operand[2][7:0]; phase<=phase+1;
260
                end else begin
261
                        address<=pc; writeEnable<=0; state<=`STATE_FETCH_OP;
262
                end
263
        end
264
endtask
265
 
266
task StoreW;
267
        begin
268
                case (phase)
269
                        0: begin cachedReg<=15; nextLoadIsDynamic<=0; address<=operand[0]+operand[1]*2; writeEnable<=1; dataOut<=operand[2][15:8]; phase<=phase+1; end
270
                        1: begin address<=address+1; dataOut<=operand[2][7:0]; phase<=phase+1; end
271
                        default: begin address<=pc; writeEnable<=0; state<=`STATE_FETCH_OP; end
272
                endcase
273
        end
274
endtask
275
 
276
task StoreRegisterAndBranch;
277
        input [7:0] regNum;
278
        input [15:0] value;
279
        input doBranch;
280
        begin
281
                state<=`STATE_STORE_REGISTER;
282
                store<=regNum;
283
                returnValue<=value;
284
                delayedBranch<=doBranch;
285
                phase<=0;
286
        end
287
endtask
288
 
289
task StoreResultAndBranch;
290
        input [15:0] result;
291
        input doBranch;
292
        begin
293
                if (store>=16) begin
294
                        address<=globalsAddress+2*(store-16);
295
                end else if (store==0) begin
296
                        address<=2*stackAddress;
297
                        stackAddress<=stackAddress+1;
298
                end else begin
299
                        address<=csStack+8+2*(store-1);
300
                end
301
                dataOut<=result[15:8];
302
                writeEnable<=1;
303
                state<=`STATE_STORE_REGISTER;
304
                returnValue[7:0]<=result[7:0];
305
                delayedBranch<=doBranch;
306
                phase<=1;
307
        end
308
endtask
309
 
310
task StoreResult;
311
        input [15:0] result;
312
        begin
313
                StoreResultAndBranch(result, negate); // negate means won't branch
314
        end
315
endtask
316
 
317
task StoreResultSlow;
318
        input [15:0] result;
319
        begin
320
                StoreRegisterAndBranch(store, result, negate); // negate means won't branch
321
        end
322
endtask
323
 
324
task ReturnFunction;
325
        input [15:0] value;
326
        begin
327
                returnValue<=value;
328
                phase<=0;
329
                state<=`STATE_RET_FUNCTION;
330
        end
331
endtask
332
 
333
task CallFunction;
334
        input doubleReturn;
335
        input noStoreOnReturn;
336
        begin
337
                negate<=doubleReturn;
338
                delayedBranch<=noStoreOnReturn;
339
                phase<=0;
340
                state<=`STATE_CALL_FUNCTION;
341
        end
342
endtask
343
 
344
task DoBranch;
345
        input result;
346
        begin
347
                if ((!result)==negate) begin
348
                        if (branch==0) begin
349
                                ReturnFunction(0);
350
                        end else if (branch==1) begin
351
                                ReturnFunction(1);
352
                        end else begin
353
                                pc<=$signed(pc)+$signed(branch)-2;
354
                                address<=$signed(pc)+$signed(branch)-2;
355
                                state<=`STATE_FETCH_OP;
356
                        end
357
                end else begin
358
                        address<=pc;
359
                        state<=`STATE_FETCH_OP;
360
                end
361
        end
362
endtask
363
 
364
task LoadAndStore;
365
        input [16:0] loadAddress;
366
        input            word;
367
        begin
368
                if (phase==0) begin
369
                        store<=data;
370
                        forceDynamicRead<=nextLoadIsDynamic;
371
                        nextLoadIsDynamic<=0;
372
                        address<=loadAddress;
373
                        temp[7:0]<=0;
374
                        phase<=word?phase+1:2;
375
                end else if (phase==1) begin
376
                        temp[7:0]<=data;
377
                        address<=address+1;
378
                        phase<=phase+1;
379
                end else begin
380
                        forceDynamicRead<=0;
381
                        StoreResultSlow((temp[7:0]<<8)|data);
382
                end
383
        end
384
endtask
385
 
386
function [16:0] GetObjectAddr;
387
        input [7:0] object;
388
        begin
389
                GetObjectAddr=objectTable+2*31+9*(object-1);
390
        end
391
endfunction
392
 
393
task TestAttr;
394
        begin
395
                if (phase==0) begin
396
                        address<=GetObjectAddr(operand[0])+(operand[1]/8); phase<=phase+1;
397
                end else begin
398
                        DoBranch(data[7-(operand[1]&7)]);
399
                end
400
        end
401
endtask
402
 
403
task SetAttr;
404
        begin
405
                case (phase)
406
                        0: begin address<=GetObjectAddr(operand[0])+(operand[1]/8); phase<=phase+1; end
407
                        1: begin dataOut<=data|(1<<(7-(operand[1]&7))); writeEnable<=1; phase<=phase+1; end
408
                        default: begin writeEnable<=0; address<=pc; state=`STATE_FETCH_OP; end
409
                endcase
410
        end
411
endtask
412
 
413
task ClearAttr;
414
        begin
415
                case (phase)
416
                        0: begin address<=GetObjectAddr(operand[0])+(operand[1]/8); phase<=phase+1; end
417
                        1: begin dataOut<=data&(~(1<<(7-(operand[1]&7)))); writeEnable<=1; phase<=phase+1; end
418
                        default: begin writeEnable<=0; address<=pc; state=`STATE_FETCH_OP; end
419
                endcase
420
        end
421
endtask
422
 
423
task JumpIfParent;
424
        begin
425
                if (phase==0) begin
426
                        address<=GetObjectAddr(operand[0])+4; phase<=phase+1;
427
                end else begin
428
                        DoBranch(operand[1]==data);
429
                end
430
        end
431
endtask
432
 
433
task GetRelative;
434
        input [1:0] offset;
435
        input branch;
436
        begin
437
                if (phase==0) begin
438
                        address<=GetObjectAddr(operand[0])+4+offset; phase<=phase+1;
439
                end else begin
440
                        StoreResultAndBranch(data, branch?data!=0:negate);
441
                end
442
        end
443
endtask
444
 
445
task FindProp;
446
        begin
447
                case (phase[2:0])
448
                        0: begin store<=data; address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end
449
                        1: begin temp[16]<=0; temp[15:8]<=data; temp[7:0]<=0; address<=address+1; phase<=phase+1; end
450
                        2: begin address<=temp|data; phase<=phase+1; end
451
                        3: begin address<=address+2*data+1; phase<=phase+1; end
452
                        4: begin
453
                                if (data==0) begin      // end of search (get default)
454
                                        address<=objectTable+2*(operand[1]-1);
455
                                        phase<=phase+1;
456
                                end else if (data[4:0]==operand[1]) begin // found property
457
                                        address<=address+1;
458
                                        if (data[7:5]==0) // only 1 byte
459
                                                phase<=6;
460
                                        else
461
                                                phase<=5;
462
                                end else begin // skip over data
463
                                        address<=address+data[7:5]+2;
464
                                end
465
                        end
466
                        5: begin temp[7:0]<=data; address<=address+1; phase<=phase+1; end
467
                        default: begin StoreResultSlow((temp[7:0]<<8)|data); end
468
                endcase
469
        end
470
endtask
471
 
472
task SetProp;
473
        begin
474
                case (phase[2:0])
475
                        0: begin address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end
476
                        1: begin temp[16]<=0; temp[15:8]<=data; temp[7:0]<=0; address<=address+1; phase<=phase+1; end
477
                        2: begin address<=temp|data; phase<=phase+1; end
478
                        3: begin address<=address+2*data+1; phase<=phase+1; end
479
                        4: begin
480
`ifndef REAL_HARDWARE
481
                                if (data==0) begin // end of search
482
                                        state<=`STATE_HALT;
483
                                end else
484
`endif
485
                                if (data[4:0]==operand[1]) begin // found property
486
                                        if (data[7:5]==0) begin // only 1 byte
487
                                                dataOut<=operand[2][7:0];
488
                                                phase<=6;
489
                                                address<=address+1;
490
                                                writeEnable<=1;
491
                                        end else begin
492
                                                dataOut<=operand[2][15:8];
493
                                                phase<=5;
494
                                                address<=address+1;
495
                                                writeEnable<=1;
496
                                        end
497
                                end else begin // skip over data
498
                                        address<=address+data[7:5]+2;
499
                                end
500
                        end
501
                        5: begin dataOut<=operand[2][7:0]; address<=address+1; phase<=phase+1; end
502
                        default: begin state<=`STATE_FETCH_OP; address<=pc; writeEnable<=0; end
503
                endcase
504
        end
505
endtask
506
 
507
task FindPropAddrLen;
508
        begin
509
                case (phase[2:0])
510
                        0: begin store<=data; address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end
511
                        1: begin temp[16]<=0; temp[15:8]<=data; temp[7:0]<=0; address<=address+1; phase<=phase+1; end
512
                        2: begin address<=temp|data; phase<=phase+1; end
513
                        3: begin address<=address+2*data+1; phase<=phase+1; end
514
                        default: begin
515
                                if (data==0) begin      // end of search
516
                                        StoreResultSlow(0);
517
                                end else if (data[4:0]==operand[1]) begin // found property
518
                                        StoreResultSlow(address+1);
519
                                end else begin // skip over data
520
                                        address<=address+data[7:5]+2;
521
                                end
522
                   end
523
                endcase
524
        end
525
endtask
526
 
527
task FindNextProp;
528
        begin
529
                case (phase[2:0])
530
                        0: begin store<=data; address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end
531
                        1: begin temp[16]<=0; temp[15:8]<=data; temp[7:0]<=0; address<=address+1; phase<=phase+1; end
532
                        2: begin address<=temp|data; phase<=phase+1; end
533
                        3: begin address<=address+2*data+1; phase<=phase+1; end
534
                        default: begin
535
                                if (operand[1]==0)
536
                                        StoreResultSlow(data[4:0]);
537
`ifndef REAL_HARDWARE
538
                                else if (data==0)       // end of search
539
                                        state<=`STATE_HALT;
540
`endif
541
                                else begin // skip over data
542
                                        if (data[4:0]==operand[1])
543
                                                operand[1]<=0;
544
                                        address<=address+data[7:5]+2;
545
                                end
546
                   end
547
                endcase
548
        end
549
endtask
550
 
551
task GetPropLen;
552
        begin
553
                if (phase==0) begin
554
                        address<=operand[0]-1; phase<=phase+1;
555
                end else begin
556
                        StoreResultSlow((operand[0]==0)?0:(data[7:5]+1));
557
                end
558
        end
559
endtask
560
 
561
task Pull;
562
        input return;
563
        begin
564
                case (phase)
565
                        0: begin
566
                                address<=2*(stackAddress-1);
567
                                forceDynamicRead<=1;
568
                                phase<=phase+1;
569
                        end
570
                        1: begin
571
                                temp[7:0]<=data;
572
                                stackAddress<=address>>1;
573
                                address<=address+1;
574
                                phase<=phase+1;
575
                        end
576
                        default: begin
577
                                forceDynamicRead<=0;
578
                                if (return) begin
579
                                        ReturnFunction((temp[7:0]<<8)|data);
580
                                end else begin
581
                                        if (operand[0]==0)
582
                                                stackAddress<=stackAddress-1;
583
                                        StoreRegisterAndBranch(operand[0], (temp[7:0]<<8)|data, negate);
584
                                end
585
                        end
586
                endcase
587
 
588
        end
589
endtask
590
 
591
task Print;
592
        input [16:0] addr;
593
        input [1:0] effect;
594
        begin
595
                temp<=addr;
596
                state<=`STATE_PRINT;
597
                returnValue[1:0]<=effect;
598
                delayedBranch<=0;
599
                phase<=0;
600
        end
601
endtask
602
 
603
task PrintObj;
604
        begin
605
                case (phase[1:0])
606
                        0: begin address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end
607
                        1: begin store<=data; address<=address+1; phase<=phase+1; end
608
                        default: Print((store<<8)+data+1, `PRINTEFFECT_FETCH);
609
                endcase
610
        end
611
endtask
612
 
613
task RemoveObject;
614
        begin
615
                case (phase[3:0])
616
                        0: begin address<=GetObjectAddr(operand[0])+4; /*obj.parent*/ phase<=phase+1; end
617
                        1: begin
618
                                if (data==0) begin
619
                                        phase<=(operand[1]!=0)?6:9;
620
                                end else begin
621
                                        phase<=phase+1;
622
                                end
623
                                temp[15:8]<=data;
624
                                writeEnable<=1;
625
                                dataOut<=operand[1];
626
                        end
627
                        2: begin writeEnable<=0; address<=address+1; /*obj.sibling*/ phase<=phase+1; end
628
                        3: begin temp[7:0]<=data; writeEnable<=1; dataOut<=0; phase<=phase+1; end
629
                        4: begin writeEnable<=0; address<=GetObjectAddr(temp[15:8])+6; /*parent.child*/ phase<=phase+1; end
630
                        5: begin
631
                                if (data==operand[0]) begin // found object
632
                                        dataOut<=temp[7:0];
633
                                        writeEnable<=1;
634
                                        phase<=(operand[1]!=0)?phase+1:9;
635
                                end else begin
636
                                        address<=GetObjectAddr(data)+5; /*follow sibling*/
637
                                end
638
                        end
639
 
640
                        6: begin address<=GetObjectAddr(operand[1])+6; writeEnable<=0; phase<=phase+1; end
641
                        7: begin temp[7:0]<=data; writeEnable<=1; dataOut<=operand[0]; phase<=phase+1; end
642
                        8: begin address<=GetObjectAddr(operand[0])+5; dataOut<=temp[7:0]; phase<=phase+1; end
643
                        default: begin
644
                                writeEnable<=0;
645
                                state<=`STATE_FETCH_OP;
646
                                address<=pc;
647
                        end
648
                endcase
649
        end
650
endtask
651
 
652
task Random;
653
        begin
654
                case (phase)
655
                        0: begin if ($signed(operand[0])<0) begin random<=operand[0]; state<=`STATE_FETCH_OP; end else begin random<=random^(random<<13); end phase<=phase+1; end
656
                        1: begin random<=random^(random>>9); phase<=phase+1; end
657
                        2: begin random<=random^(random<<7); phase<=phase+1; end
658
                        default: begin state<=`STATE_DIVIDE; delayedBranch<=1; divideAddOne<=1; operand[1]<=operand[0]; operand[0]<=random&'h7FFF; phase<=0; end
659
                endcase
660
        end
661
endtask
662
 
663
task PrintNum;
664
        begin
665
`ifdef HARDWARE_PRINT
666
                case (phase)
667
                        0: begin negate<=0; operand[1]<=1; operand[2][2:0]<=2; operand[3][3:0]<=0; phase<=phase+1; end
668
                        1,2,3,4: begin operand[1]<=(operand[1]<<3)+(operand[1]<<1); printEnable<=0; phase<=phase+1; end
669
                        5: begin
670
                                if (operand[0]>=operand[1]) begin
671
                                        operand[0]<=operand[0]-operand[1];
672
                                        operand[3][3:0]<=operand[3][3:0]+1;
673
                                        negate<=1;
674
                                        printEnable<=0;
675
                                end else begin
676
                                        printEnable<=negate;
677
                                        dataOut<=operand[3][3:0]+48;
678
                                        operand[3][3:0]<=0;
679
                                        operand[1]<=1;
680
                                        operand[2][2:0]<=operand[2][2:0]+1;
681
                                        phase<=operand[2][2:0];
682
                                end
683
                        end
684
                        default: begin printEnable<=0; state<=`STATE_FETCH_OP; end
685
                endcase
686
`else
687
                operand[0]<=`PRINTNUM_CALLBACK;
688
                operand[1]<=operand[0];
689
                operTypes[1]<=`OPER_LARGE;
690
                CallFunction(0, 1);
691
`endif
692
        end
693
endtask
694
 
695
task PrintChar;
696
        input [7:0] char;
697
        begin
698
                $display("Print char: %d\n", char);
699
`ifdef HARDWARE_PRINT
700
                printEnable<=1;
701
                dataOut<=char;
702
                state<=`STATE_PRINT_CHAR;
703
`else
704
                operand[0]<=`PRINTCHAR_CALLBACK;
705
                operand[1]<=char;
706
                operTypes[1]<=`OPER_LARGE;
707
                CallFunction(0, 1);
708
`endif
709
        end
710
endtask
711
 
712
task SRead;
713
        begin
714
                operand[0]<=`READ_CALLBACK;
715
                operand[2]<=operand[0]; // Am swapping arguments just to save space on FPGA
716
                operTypes[2]<=`OPER_LARGE;
717
                CallFunction(0, 1);
718
        end
719
endtask
720
 
721
task WriteReg;
722
        begin
723
                case (phase)
724
                        0: begin lastWriteWasDraw<=(operand[0]=='h22); if (operand[0]=='h22 && lastWriteWasDraw) begin rlcdRS<=1; phase<=4; end else begin rlcdRS<=0; phase<=phase+1; end end
725
                        1: begin dataOut<=operand[0][15:8]; printEnable<=1; phase<=phase+1; end
726
                        2: begin dataOut<=operand[0][7:0]; if (operand[0]==0) phase<=4; else phase<=phase+1; end
727
                        3: begin rlcdRS<=1; printEnable<=0; phase<=phase+1; end
728
                        4: begin dataOut<=operand[1][15:8]; printEnable<=1; phase<=phase+1; end
729
                        5: begin dataOut<=operand[1][7:0]; phase<=phase+1; end
730
                        default: begin printEnable<=0; address<=pc; state<=`STATE_FETCH_OP; end
731
                endcase
732
        end
733
endtask
734
 
735
task Blit1;
736
        begin
737
                case (phase)
738
                        0: begin forceDynamicRead<=1; rlcdRS<=0; phase<=phase+1; end
739
                        1: begin dataOut<=0; printEnable<=1; phase<=phase+1; end
740
                        2: begin address<=operand[0]*2; dataOut<=34; returnValue<=0; phase<=phase+1; end
741
                        3: begin
742
                                rlcdRS<=1;
743
                                printEnable<=0;
744
                                if (operand[1]==0) begin
745
                                        forceDynamicRead<=0;
746
                                        address<=pc;
747
                                        state<=`STATE_FETCH_OP;
748
                                end
749
                                phase<=phase+1;
750
                        end
751
                        4: begin
752
                                store<=data;
753
                                dataOut<=data[7]?operand[3][15:8]:operand[2][15:8];
754
                                printEnable<=1;
755
                                phase<=6;
756
                        end
757
                        5: begin
758
                                dataOut<=store[7]?operand[3][15:8]:operand[2][15:8];
759
                                printEnable<=1;
760
                                phase<=phase+1;
761
                        end
762
                        default: begin
763
                                dataOut<=store[7]?operand[3][7:0]:operand[2][7:0];
764
                                store[7:1]=store[6:0];
765
                                returnValue<=returnValue+1;
766
                                if (returnValue[2:0]==7) begin
767
                                        operand[1]=operand[1]-1;
768
                                        phase<=3;
769
                                        address<=address+1;
770
                                end else begin
771
                                        phase<=5;
772
                                end
773
                        end
774
                endcase
775
        end
776
endtask
777
 
778
task GetTouch;
779
        begin
780
                case (phase)
781
                        0: begin
782
                                adcCS<=1;
783
                                adcClk<=0;
784
                                adcDin<=1;
785
                                operand[1]<='hffff;
786
                           operand[2]<=1;
787
                                phase<=1;
788
                        end
789
                        1: begin
790
                                operand[2][3:0]<=operand[2][3:0]+1;
791
                                if (operand[2][3:0]==0) begin                   // Max clock rate for ADC is ~ 1MHz so divide our clock by 16
792
                                        adcClk<=1;
793
                                        operand[1]<=(operand[1]<<1)+adcDout;
794
                                        phase<=(!operand[1][9])?3:2;
795
                                end
796
                        end
797
                        2: begin
798
                                operand[2][3:0]<=operand[2][3:0]+1;
799
                                if (operand[2][3:0]==0) begin                   // Max clock rate for ADC is ~ 1MHz so divide our clock by 16
800
                                        operand[0][8:4]<=(operand[0][8:4]>>1);
801
                                        adcDin<=operand[0][4];
802
                                        adcClk<=0;
803
                                        phase<=1;
804
                                end
805
                        end
806
                        default: begin adcCS<=0; StoreResultSlow(operand[1]&'h3FF); end
807
                endcase
808
        end
809
endtask
810
 
811
task DoOp;
812
        begin
813
                case (operNum)
814
                        `OP_0: begin
815
                                if (phase==0)
816
                                        $display("PC:%h Doing op0:%d Store:%h Branch:%h/%d", curPC, op, operand[0], store, branch, negate);
817
                                case (op[3:0])
818
                                        `OP0_RTRUE: ReturnFunction(1);
819
                                        `OP0_RFALSE: ReturnFunction(0);
820
                                        `OP0_PRINT: Print(pc, `PRINTEFFECT_FETCHAFTER);
821
                                        `OP0_PRINTRET: Print(pc, `PRINTEFFECT_RET1);
822
                                        `OP0_SAVE,`OP0_RESTORE: DoBranch(0);
823
                                        `OP0_RESTART: state<=`STATE_RESET;
824
                                        `OP0_RETPOP: Pull(1);
825
                                        `OP0_QUIT: begin operand[0]<=`QUIT_CALLBACK; CallFunction(0,1); end
826
                                        `OP0_NEWLINE: PrintChar(10);
827
                                        `OP0_SHOWSTATUS: begin operand[0]<=`STATUS_CALLBACK; CallFunction(0,1); end
828
                                        `OP0_VERIFY: DoBranch(1);
829
                                        default: state<=`STATE_HALT;
830
                                endcase
831
                        end
832
                        `OP_1: begin
833
                                if (phase==0)
834
                                        $display("PC:%h Doing op1:%d Operands:%h Store:%h Branch:%h/%d", curPC, op, operand[0], store, branch, negate);
835
                                case (op[3:0])
836
                                        `OP1_JZ: DoBranch(operand[0]==0);
837
                                        `OP1_GETSIBLING: GetRelative(1,1);
838
                                        `OP1_GETCHILD: GetRelative(2,1);
839
                                        `OP1_GETPARENT: GetRelative(0,0);
840
                                        `OP1_GETPROPLEN: GetPropLen();
841
                                        `OP1_INC: StoreResult(operand[0]+1);
842
                                        `OP1_DEC: StoreResult(operand[0]-1);
843
                                        `OP1_PRINTADDR: Print(operand[0], `PRINTEFFECT_FETCH);
844
                                        `OP1_SWITCHBANK: begin a17<=operand[0][0]; a18<=operand[0][1]; state<=`STATE_RESET; end
845
                                        `OP1_REMOVEOBJ: begin operNum<=`OP_2; op<=`OP2_INSERTOBJ; operand[1]<=0; end
846
                                        `OP1_PRINTOBJ: PrintObj();
847
                                        `OP1_RET: ReturnFunction(operand[0]);
848
                                        `OP1_JUMP: begin pc<=$signed(pc)+$signed(operand[0])-2; address<=$signed(pc)+$signed(operand[0])-2; state<=`STATE_FETCH_OP; end
849
                                        `OP1_PRINTPADDR: Print(2*operand[0], `PRINTEFFECT_FETCH);
850
                                        `OP1_LOAD: StoreResult(operand[0]);
851
                                        `OP1_NOT: StoreResult(~operand[0]);
852
                                        default: state<=`STATE_HALT;
853
                                endcase
854
                        end
855
                        `OP_2: begin
856
                                if (phase==0)
857
                                        $display("PC:%h Doing op2:%d Operands:%h %h Store:%h Branch:%h/%d/%h", curPC, op, operand[0], operand[1], store, branch, negate, $signed(pc)+$signed(branch-2));
858
                                case (op)
859
                                        `OP2_JE: DoBranch(operand[0]==operand[1] || (operTypes[2]!=`OPER_OMIT && operand[0]==operand[2]) || (operTypes[3]!=`OPER_OMIT && operand[0]==operand[3]));
860
                                        `OP2_JL: DoBranch($signed(operand[0])<$signed(operand[1]));
861
                                        `OP2_JG: DoBranch($signed(operand[0])>$signed(operand[1]));
862
                                        `OP2_INC_CHK: StoreResultAndBranch(operand[0]+1, $signed(operand[0])+1>$signed(operand[1]));
863
                                        `OP2_DEC_CHK: StoreResultAndBranch(operand[0]-1, $signed(operand[0])-1<$signed(operand[1]));
864
                                        `OP2_JIN: JumpIfParent();
865
                                        `OP2_TEST: DoBranch((operand[0]&operand[1])==operand[1]);
866
                                        `OP2_OR: StoreResult(operand[0]|operand[1]);
867
                                        `OP2_AND: StoreResult(operand[0]&operand[1]);
868
                                        `OP2_TESTATTR: TestAttr();
869
                                        `OP2_SETATTR: SetAttr();
870
                                        `OP2_CLEARATTR: ClearAttr();
871
                                        `OP2_STORE: begin if (operand[0]==0) stackAddress<=stackAddress-1; StoreRegisterAndBranch(operand[0], operand[1], negate); end
872
                                        `OP2_INSERTOBJ: RemoveObject();
873
                                        `OP2_LOADW: LoadAndStore(operand[0]+2*operand[1], 1);
874
                                        `OP2_LOADB: LoadAndStore(operand[0]+operand[1], 0);
875
                                        `OP2_GETPROP: FindProp();
876
                                        `OP2_GETPROPADDR: FindPropAddrLen();
877
                                        `OP2_GETNEXTPROP: FindNextProp();
878
                                        `OP2_ADD: StoreResult($signed(operand[0])+$signed(operand[1]));
879
                                        `OP2_SUB: StoreResult($signed(operand[0])-$signed(operand[1]));
880
                                        `OP2_MUL: StoreResult($signed(operand[0])*$signed(operand[1]));
881
                                        `OP2_DIV: begin store<=data; state=`STATE_DIVIDE; delayedBranch<=0; divideAddOne<=0; end
882
                                        `OP2_MOD: begin store<=data; state=`STATE_DIVIDE; delayedBranch<=1; divideAddOne<=0; end
883
                                        `OP2_WRITEREG: WriteReg();
884
                                        default: state<=`STATE_HALT;
885
                                endcase
886
                        end
887
                        default: begin // 'OP_VAR
888
                                if (phase==0) begin
889
                                        if (operTypes[0]==`OPER_OMIT)
890
                                                $display("PC:%h Doing opvar:%d Operands: Store:%h Branch:%h/%d/%h", curPC, op, store, branch, negate, $signed(pc)+$signed(branch-2));
891
                                        else if (operTypes[1]==`OPER_OMIT)
892
                                                $display("PC:%h Doing opvar:%d Operands:%h Store:%h Branch:%h/%d/%h", curPC, op, operand[0], store, branch, negate, $signed(pc)+$signed(branch-2));
893
                                        else if (operTypes[2]==`OPER_OMIT)
894
                                                $display("PC:%h Doing opvar:%d Operands:%h %h Store:%h Branch:%h/%d/%h", curPC, op, operand[0], operand[1], store, branch, negate, $signed(pc)+$signed(branch-2));
895
                                        else if (operTypes[3]==`OPER_OMIT)
896
                                                $display("PC:%h Doing opvar:%d Operands:%h %h %h Store:%h Branch:%h/%d/%h", curPC, op, operand[0], operand[1], operand[2], store, branch, negate, $signed(pc)+$signed(branch-2));
897
                                        else
898
                                                $display("PC:%h Doing opvar:%d Operands:%h %h %h %h Store:%h Branch:%h/%d/%h", curPC, op, operand[0], operand[1], operand[2], operand[3], store, branch, negate, $signed(pc)+$signed(branch-2));
899
                                end
900
                                case (op)
901
                                        `OPVAR_CALL: if (operand[0]==0) StoreResultSlow(0); else CallFunction(0, 0);
902
                                        `OPVAR_STOREW: StoreW();
903
                                        `OPVAR_STOREB: StoreB();
904
                                        `OPVAR_PUTPROP: SetProp();
905
                                        `OPVAR_SREAD: SRead();
906
                                        `OPVAR_PRINTCHAR: PrintChar(operand[0]);
907
                                        `OPVAR_PRINTNUM: PrintNum();
908
                                        `OPVAR_RANDOM: Random();
909
                                        `OPVAR_PUSH: StoreRegisterAndBranch(0, operand[0], negate);
910
                                        `OPVAR_PULL: Pull(0);
911
                                        `OPVAR_GETTOUCH: GetTouch();
912
                                        `OPVAR_BLIT1: Blit1();
913
                                        default: state<=`STATE_HALT;
914
                                endcase
915
                        end
916
                endcase
917
        end
918
endtask
919
 
920
`ifdef HARDWARE_PRINT
921
task DoPrint;
922
        input [4:0] char;
923
        begin
924
                if (delayedBranch) begin
925
                        store[4:0]<=char;
926
                        operand[1]<=phase+1;
927
                        delayedBranch<=0;
928
                        phase<=6;
929
                end else if (long==1) begin
930
                        operand[3][4:0]=char;
931
                        long<=long+1;
932
                end else if (long==2) begin
933
                        printEnable<=1;
934
                        dataOut<=(operand[3][4:0]<<5)|char;
935
                        long<=0;
936
                end else begin
937
                        phase<=phase+1;
938
                        if (char==0) begin
939
                                printEnable<=1;
940
                                dataOut<=32;
941
                        end else if (char==4 || char==5) begin
942
                                printEnable<=0;
943
                                alphabet=char-3;
944
                        end else if (char>=6) begin
945
                                printEnable<=!(alphabet==2 && char==6);
946
                                if (alphabet==2) begin
947
                                        case (char)
948
                                                6: long<=1;
949
                                                7: dataOut<=10;
950
                                                8,9,10,11,12,13,14,15,16,17: dataOut<=char-8+48;
951
                                                18: dataOut<=46;
952
                                                19: dataOut<=44;
953
                                                20: dataOut<=33;
954
                                                21: dataOut<=63;
955
                                                22: dataOut<=95;
956
                                                23: dataOut<=35;
957
                                                24: dataOut<=39;
958
                                                25: dataOut<=34;
959
                                                26: dataOut<=47;
960
                                                27: dataOut<=92;
961
                                                28: dataOut<=45;
962
                                                29: dataOut<=58;
963
                                                30: dataOut<=40;
964
                                                31: dataOut<=41;
965
                                        endcase
966
                                end else begin
967
                                        dataOut<=char-6+((alphabet==0)?97:65);
968
                                end
969
                                alphabet<=0;
970
                        end else begin
971
                                printEnable<=0;
972
                                store[7:5]<=(char-1);
973
                                delayedBranch<=1;
974
                        end
975
                end
976
        end
977
endtask
978
`endif
979
 
980
task FinishReadingOps;
981
begin
982
        case (operNum)
983
                `OP_1: begin
984
                        case (op[3:0])
985
                                `OP1_INC, `OP1_DEC, `OP1_LOAD: state<=`STATE_READ_INDIRECT;
986
                                `OP1_GETSIBLING,`OP1_GETCHILD,`OP1_GETPARENT,`OP1_GETPROPLEN,`OP1_NOT: state<=`STATE_READ_STORE;
987
                                `OP1_JZ: state<=`STATE_READ_BRANCH;
988
                                default: state<=`STATE_DO_OP;
989
                        endcase
990
                        pc<=pc+1;
991
                end
992
                `OP_2: begin
993
                        case (op[4:0])
994
                                `OP2_INC_CHK,`OP2_DEC_CHK: begin pc<=pc+1; state<=`STATE_READ_INDIRECT; end
995
                                `OP2_OR,`OP2_AND,`OP2_ADD,`OP2_SUB,`OP2_MUL: begin pc<=pc+1; state<=`STATE_READ_STORE; end
996
                                `OP2_LOADW,`OP2_LOADB,`OP2_GETPROP ,`OP2_GETPROPADDR,`OP2_GETNEXTPROP,`OP2_DIV,`OP2_MOD: begin pc<=pc+2; state<=`STATE_DO_OP; end
997
                                `OP2_JE,`OP2_JL,`OP2_JG,`OP2_JIN,`OP2_TEST,`OP2_TESTATTR: begin pc<=pc+1; state<=`STATE_READ_BRANCH; end
998
                                default: begin pc<=pc+1; state<=`STATE_DO_OP; end
999
                        endcase
1000
                end
1001
                default: begin // `OP_VAR
1002
                        pc<=pc+1;
1003
                        case (op[4:0])
1004
                                `OPVAR_CALL,`OPVAR_RANDOM,`OPVAR_GETTOUCH: state<=`STATE_READ_STORE;
1005
                                default: state<=`STATE_DO_OP;
1006
                        endcase
1007
                end
1008
        endcase
1009
end
1010
endtask
1011
 
1012
always @ (posedge clk)
1013
begin
1014
        case(state)
1015
                `STATE_RESET: begin
1016
                        case (phase)
1017
                                0: begin printEnable<=0; random<=1; forceStaticRead<=1; address<='h6; phase<=phase+1; end
1018
                                1: begin address<='h7; phase<=phase+1; pc[15:8]<=data; pc[16]<=0; end
1019
                                2: begin address<='hA; phase<=phase+1; pc[7:0]<=data; end
1020
                                3: begin address<='hB; phase<=phase+1; objectTable[15:8]<=data; end
1021
                                4: begin address<='hC; phase<=phase+1; objectTable[7:0]<=data; end
1022
                                5: begin address<='hD; phase<=phase+1; globalsAddress[15:8]<=data; end
1023
                                6: begin address<=0; phase<=phase+1; globalsAddress[7:0]<=data; end
1024
                                7: begin dataOut<=data; writeEnable<=1; phase<=8; end
1025
                                8: begin writeEnable<=0; address<=address+1; if (address[15:0]=='hffff) phase<=9; else phase<=7; end
1026
                                9: begin writeEnable<=1; dataOut<=0; address<=address+1; if (address[15:0]=='hffff) begin writeEnable<=0; phase<=10; end end
1027
                                10: begin rlcdReset<=address[10]; rlcdRS<=1; printEnable<=0; address<=address+1; if (address[10:0]=='h7ff) phase<=11; end
1028
                                default: begin
1029
                                        cachedReg<=15;
1030
                                        address<=pc;
1031
                                        forceStaticRead<=0;
1032
                                        stackAddress<=64*1024/2;
1033
                                        csStack<=65*1024;
1034
                                        operand[0]<=`INIT_CALLBACK;
1035
                                        operTypes[1]<=`OPER_OMIT;
1036
                                        CallFunction(0, 1);
1037
                                end
1038
                        endcase
1039
                end
1040
                `STATE_CALL_FUNCTION: begin
1041
                        case (phase)
1042
                                0: begin $display("Call function %h", operand[0]*2); address<=csStack; writeEnable<=1; dataOut<=(delayedBranch<<2)|(negate<<1)|pc[16]; phase<=phase+1; end
1043
                                1: begin address<=address+1; dataOut<=pc[15:8]; phase<=phase+1; end
1044
                                2: begin address<=address+1; dataOut<=pc[7:0]; phase<=4; end
1045
                                3: begin end // pointless phase but for some reason saves gates
1046
                                4: begin address<=address+1; dataOut<=stackAddress[15:8]; phase<=phase+1; end
1047
                                5: begin address<=address+1; dataOut<=stackAddress[7:0]; phase<=phase+1; end
1048
                                6: begin address<=address+1; dataOut<=store; phase<=(operand[0][15:3]==0)?phase+1:10; end
1049
                                7: begin address<=`CALLBACK_BASE+5*(operand[0]&7); writeEnable<=0; phase<=phase+1; end
1050
                                8: begin address<=address+1; operand[0][15:8]<=data; phase<=phase+1; end
1051
                                9: begin operand[0][7:0]<=data; phase<=phase+1; end
1052
                                default: begin
1053
                                        cachedReg<=15;
1054
                                        csStack<=csStack+38;
1055
                                        address<=2*operand[0];
1056
                                        state<=`STATE_READ_FUNCTION;
1057
                                        writeEnable<=0;
1058
                                        phase<=0;
1059
                                end
1060
                        endcase
1061
                end
1062
                `STATE_RET_FUNCTION: begin
1063
                        case (phase)
1064
                                0: begin csStack<=csStack-38; address<=csStack-38; forceDynamicRead<=1; phase<=phase+1; end
1065
                                1: begin pc[16]<=data[0]; negate<=data[1]; delayedBranch<=data[2]; address<=address+1; phase<=phase+1; end
1066
                                2: begin pc[15:8]<=data; address<=address+1; phase<=phase+1; end
1067
                                3: begin pc[7:0]<=data; address<=address+1; phase<=phase+1; end
1068
                                4: begin stackAddress[15:8]<=data; address<=address+1; phase<=phase+1; end
1069
                                5: begin stackAddress[7:0]<=data; address<=address+1; phase<=phase+1; end
1070
                                default: begin
1071
                                        forceDynamicRead<=0;
1072
                                        cachedReg<=15;
1073
                                        if (negate) begin
1074
                                                phase<=0;
1075
                                        end else if (delayedBranch) begin
1076
                                                state<=`STATE_FETCH_OP;
1077
                                                address<=pc;
1078
                                        end else begin
1079
                                                StoreRegisterAndBranch(data, returnValue, negate);
1080
                                        end
1081
                                end
1082
                        endcase
1083
                end
1084
                `STATE_READ_FUNCTION: begin
1085
                        case (phase)
1086
                                0: begin
1087
                                        if (data==0) begin
1088
                                                state<=`STATE_FETCH_OP;
1089
                                        end else begin
1090
                                                opsToRead<=4*data-1;
1091
                                                phase<=phase+1;
1092
                                        end
1093
                                        currentLocal<=0;
1094
                                        pc<=address+1;
1095
                                        address<=address+1;
1096
                                end
1097
                                default: begin
1098
                                        if (opsToRead&1) begin
1099
                                                if (currentLocal<6 && operTypes[(currentLocal>>1)+1]!=`OPER_OMIT) begin
1100
                                                        dataOut<=currentLocal[0]?operand[(currentLocal>>1)+1][7:0]:operand[(currentLocal>>1)+1][15:8];
1101
                                                end else begin
1102
                                                        dataOut<=data;
1103
                                                end
1104
                                                address<=csStack+8+currentLocal;
1105
                                                writeEnable<=1;
1106
                                                currentLocal<=currentLocal+1;
1107
                                        end else begin
1108
                                                pc<=pc+1;
1109
                                                address<=pc+1;
1110
                                                writeEnable<=0;
1111
                                        end
1112
                                        if (opsToRead==0) begin
1113
                                                state<=`STATE_FETCH_OP;
1114
                                        end
1115
                                        opsToRead<=opsToRead-1;
1116
                                end
1117
                        endcase
1118
                end
1119
                `STATE_FETCH_OP: begin
1120
                        phase<=0;
1121
                        operTypes[2]<=`OPER_OMIT;
1122
                        operTypes[3]<=`OPER_OMIT;
1123
                        operTypes[4]<=`OPER_OMIT;
1124
                        curPC<=pc;
1125
                        $display("Fetching op at %h", pc);
1126
                        if (!reset) begin
1127
                                state<=`STATE_RESET;
1128
                                a17<=0;
1129
                                a18<=0;
1130
                        end else begin
1131
                                case (data[7:6])
1132
                                        2'b10: begin
1133
                                                // short form
1134
                                                op[4:0]<=data[3:0];
1135
                                                operTypes[0]<=data[5:4];
1136
                                                operTypes[1]<=`OPER_OMIT;
1137
                                                if (data[5:4]==2'b11) begin
1138
                                                        operNum[1:0]<=`OP_0;
1139
                                                        case (data[3:0])
1140
                                                                `OP0_POP: begin cachedReg<=15; stackAddress<=stackAddress-1; end
1141
                                                                `OP0_NOP: begin /*nop*/ end
1142
                                                                `OP0_DYNAMIC: nextLoadIsDynamic<=1;
1143
                                                                `OP0_SAVE,`OP0_RESTORE,`OP0_VERIFY: state<=`STATE_READ_BRANCH;
1144
                                                                default: state<=`STATE_DO_OP;
1145
                                                        endcase
1146
                                                end else begin
1147
                                                        operNum[1:0]<=`OP_1;
1148
                                                        state<=`STATE_READ_OPERS;
1149
                                                end
1150
                                        end
1151
                                        2'b11: begin
1152
                                                // variable form
1153
                                                op[4:0]<=data[4:0];
1154
                                                operNum[1:0]<=(data[5]?`OP_VAR:`OP_2);
1155
                                                state<=`STATE_READ_TYPES;
1156
                                        end
1157
                                        default: begin
1158
                                                // long form
1159
                                                op[4:0]<=data[4:0];
1160
                                                operNum[1:0]<=`OP_2;
1161
                                                operTypes[0]<=(data[6] ? `OPER_VARI : `OPER_SMALL);
1162
                                                operTypes[1]<=(data[5] ? `OPER_VARI : `OPER_SMALL);
1163
                                                state<=`STATE_READ_OPERS;
1164
                                        end
1165
                                endcase
1166
                        end
1167
                        operandIdx<=0;
1168
                        pc<=pc+1;
1169
                        address<=pc+1;
1170
                end
1171
                `STATE_READ_TYPES: begin
1172
                        operTypes[0]<=data[7:6];
1173
                        operTypes[1]<=data[5:4];
1174
                        operTypes[2]<=data[3:2];
1175
                        operTypes[3]<=data[1:0];
1176
                        address<=pc+1;
1177
                        if (data[7:6]==`OPER_OMIT)
1178
                                FinishReadingOps();
1179
                        else begin
1180
                                state<=`STATE_READ_OPERS;
1181
                                pc<=pc+1;
1182
                        end
1183
                end
1184
                `STATE_READ_OPERS: begin
1185
                        case (operTypes[operandIdx])
1186
                                `OPER_SMALL: begin
1187
                                        operand[operandIdx]<=data[7:0];
1188
                                        address<=pc+1;
1189
                                        operandIdx<=operandIdx+1;
1190
                                        if (operTypes[operandIdx+1]==`OPER_OMIT)
1191
                                                FinishReadingOps();
1192
                                        else
1193
                                                pc<=pc+1;
1194
                                end
1195
                                `OPER_LARGE: begin
1196
                                        address<=pc+1;
1197
                                        if (!readHigh) begin
1198
                                                operand[operandIdx][15:8]<=data[7:0];
1199
                                                readHigh<=1;
1200
                                                pc<=pc+1;
1201
                                        end else begin
1202
                                                operand[operandIdx][7:0]<=data[7:0];
1203
                                                operandIdx<=operandIdx+1;
1204
                                                readHigh<=0;
1205
                                                if (operTypes[operandIdx+1]==`OPER_OMIT)
1206
                                                        FinishReadingOps();
1207
                                                else
1208
                                                        pc<=pc+1;
1209
                                        end
1210
                                end
1211
                                default: begin // OPER_VARI
1212
                                        case (phase)
1213
                                                0: begin
1214
                                                        if (data==0) begin
1215
                                                                stackAddress<=stackAddress-1;
1216
                                                        end
1217
                                                        if (cachedReg!=15 && data==cachedReg) begin
1218
                                                                operand[operandIdx]<=cachedValue;
1219
                                                                address<=pc+1;
1220
                                                                operandIdx<=operandIdx+1;
1221
                                                                if (operTypes[operandIdx+1]==`OPER_OMIT)
1222
                                                                        FinishReadingOps();
1223
                                                                else
1224
                                                                        pc<=pc+1;
1225
                                                                if (cachedReg==0)
1226
                                                                        cachedReg<=15;
1227
                                                        end else begin
1228
                                                                if (data>=16) begin
1229
                                                                        address<=globalsAddress+2*(data-16);
1230
                                                                end else if (data==0) begin
1231
                                                                        address<=2*(stackAddress-1);
1232
                                                                end else begin
1233
                                                                        address<=csStack+8+2*(data-1);
1234
                                                                end
1235
                                                                forceDynamicRead<=1;
1236
                                                                phase<=phase+1;
1237
                                                        end
1238
                                                end
1239
                                                1: begin
1240
                                                        operand[operandIdx]<=(data<<8);
1241
                                                        address<=address+1;
1242
                                                        phase<=phase+1;
1243
                                                end
1244
                                                default: begin
1245
                                                        forceDynamicRead<=0;
1246
                                                        operand[operandIdx]<=operand[operandIdx]|data;
1247
                                                        address<=pc+1;
1248
                                                        operandIdx<=operandIdx+1;
1249
                                                        if (operTypes[operandIdx+1]==`OPER_OMIT)
1250
                                                                FinishReadingOps();
1251
                                                        else
1252
                                                                pc<=pc+1;
1253
                                                        phase<=0;
1254
                                                end
1255
                                        endcase
1256
                                end
1257
                        endcase
1258
                end
1259
                `STATE_READ_INDIRECT: begin
1260
                        case (phase)
1261
                                0: begin
1262
                                        cachedReg<=15;
1263
                                        store<=operand[0];
1264
                                        if (operand[0]>=16) begin
1265
                                                address<=globalsAddress+2*(operand[0]-16);
1266
                                        end else if (operand[0]==0) begin
1267
                                                if (op[4:0]!=`OP1_LOAD)
1268
                                                        stackAddress<=stackAddress-1;
1269
                                                address<=2*(stackAddress-1);
1270
                                        end else begin
1271
                                                address<=csStack+8+2*(operand[0]-1);
1272
                                        end
1273
                                        forceDynamicRead<=1;
1274
                                        phase<=phase+1;
1275
                                end
1276
                                1: begin
1277
                                        operand[0][15:8]<=data;
1278
                                        address<=address+1;
1279
                                        phase<=phase+1;
1280
                                end
1281
                                default: begin
1282
                                        forceDynamicRead<=0;
1283
                                        operand[0][7:0]<=data;
1284
                                        if (op[4:0]==`OP1_LOAD)
1285
                                                state<=`STATE_READ_STORE;
1286
                                        else if (operNum==`OP_2)
1287
                                                state<=`STATE_READ_BRANCH;
1288
                                        else
1289
                                                state<=`STATE_DO_OP;
1290
                                        address<=pc;
1291
                                        phase<=0;
1292
                                end
1293
                        endcase
1294
                end
1295
                `STATE_READ_STORE: begin
1296
                        case (op[4:0])
1297
                                `OP1_GETSIBLING, `OP1_GETCHILD: state<=`STATE_READ_BRANCH;
1298
                                default: state<=`STATE_DO_OP;
1299
                        endcase
1300
                        store<=data;
1301
                        pc<=pc+1;
1302
                        address<=pc+1;
1303
                end
1304
                `STATE_READ_BRANCH: begin
1305
                        if (!readHigh) begin
1306
                                if (data[6]) begin
1307
                                        branch<=data[5:0];
1308
                                        negate<=!data[7];
1309
                                        state<=`STATE_DO_OP;
1310
                                end else begin
1311
                                        branch[13:8]<=data[5:0];
1312
                                        negate<=!data[7];
1313
                                        readHigh<=1;
1314
                                end
1315
                        end else begin
1316
                                branch[7:0]<=data;
1317
                                readHigh<=0;
1318
                                state<=`STATE_DO_OP;
1319
                        end
1320
                        pc<=pc+1;
1321
                        address<=pc+1;
1322
                end
1323
                `STATE_DO_OP: begin
1324
                        DoOp();
1325
                end
1326
                `STATE_STORE_REGISTER: begin
1327
                        case (phase)
1328
                                0: begin
1329
                                        if (store>=16) begin
1330
                                                address<=globalsAddress+2*(store-16);
1331
                                        end else if (store==0) begin
1332
                                                address<=2*stackAddress;
1333
                                                stackAddress<=stackAddress+1;
1334
                                        end else begin
1335
                                                address<=csStack+8+2*(store-1);
1336
                                        end
1337
                                        dataOut<=returnValue[15:8];
1338
                                        writeEnable<=1;
1339
                                        phase<=phase+1;
1340
                                end
1341
                                1: begin
1342
                                        cachedReg<=store;
1343
                                        cachedValue[15:8]<=dataOut;
1344
                                        cachedValue[7:0]<=returnValue[7:0];
1345
                                        dataOut<=returnValue[7:0];
1346
                                        address<=address+1;
1347
                                        phase<=phase+1;
1348
                                end
1349
                                default: begin
1350
                                        DoBranch(delayedBranch);
1351
                                        writeEnable<=0;
1352
                                        phase<=0;
1353
                                end
1354
                        endcase
1355
                end
1356
                `STATE_DIVIDE: begin
1357
                        case (phase)
1358
                                0: begin
1359
                                        negate<=operand[0][15]^operand[1][15];
1360
                                        readHigh<=operand[0][15];
1361
                                        if ($signed(operand[0])<0)
1362
                                                operand[0]<=-operand[0];
1363
                                        else
1364
                                                operand[0]<=operand[0];
1365
`ifndef REAL_HARDWARE
1366
                                        if (operand[1]==0)
1367
                                                state=`STATE_HALT;
1368
                                        else
1369
`endif
1370
                                        if ($signed(operand[1])<0)
1371
                                                operand[1]<=-operand[1];
1372
                                        operand[2]<=1;
1373
                                        operand[3]<=0;
1374
                                        phase<=phase+1;
1375
                                end
1376
                                1: begin
1377
                                        if (operand[1][15] || operand[0]<=operand[1]) begin
1378
                                                phase<=phase+1;
1379
                                        end else begin
1380
                                                operand[1]<=operand[1]<<1;
1381
                                                operand[2]<=operand[2]<<1;
1382
                                        end
1383
                                end
1384
                                2: begin
1385
                                        if (operand[1]>operand[0]) begin
1386
                                                if (operand[2]==1) begin
1387
                                                        if (negate) begin
1388
                                                                operand[0]<=-operand[3];
1389
                                                        end else begin
1390
                                                                operand[0]<=operand[3];
1391
                                                        end
1392
                                                        if (readHigh) begin
1393
                                                                operand[1]<=-operand[0];
1394
                                                        end else begin
1395
                                                                operand[1]<=operand[0];
1396
                                                        end
1397
                                                        readHigh<=0;
1398
                                                        phase<=phase+1;
1399
                                                end else begin
1400
                                                        operand[1]<=operand[1]>>1;
1401
                                                        operand[2]<=operand[2]>>1;
1402
                                                end
1403
                                        end else begin
1404
                                                operand[0]<=operand[0]-operand[1];
1405
                                                operand[3]<=operand[3]+operand[2];
1406
                                        end
1407
                                end
1408
                                default: begin
1409
                                        StoreResultSlow(delayedBranch?(operand[1]+divideAddOne):operand[0]);
1410
                                end
1411
                        endcase
1412
                end
1413
                `STATE_PRINT: begin
1414
`ifdef HARDWARE_PRINT
1415
                        case (phase)
1416
                                0: begin delayedValue[15:8]<=data; address<=address+1; phase<=phase+1; end
1417
                                1: begin delayedValue[7:0] <=data; address<=address+1; phase<=phase+1; end
1418
                                2,3,4: begin DoPrint(delayedValue[14:10]); delayedValue[14:5]<=delayedValue[9:0]; end
1419
                                5: begin
1420
                                        printEnable<=0;
1421
                                        if (delayedValue[15]) begin
1422
                                                alphabet<=0;
1423
                                                long<=0;
1424
                                                case (returnValue[1:0])
1425
                                                        `PRINTEFFECT_FETCH: begin
1426
                                                                address<=pc;
1427
                                                                state<=`STATE_FETCH_OP;
1428
                                                        end
1429
                                                        `PRINTEFFECT_FETCHAFTER: begin
1430
                                                                pc<=address;
1431
                                                                state<=`STATE_FETCH_OP;
1432
                                                        end
1433
                                                        `PRINTEFFECT_RET1: begin
1434
                                                                ReturnFunction(1);
1435
                                                        end
1436
                                                        `PRINTEFFECT_ABBREVRET: begin
1437
                                                                address<=temp;
1438
                                                                delayedValue<=operand[0];
1439
                                                                phase<=operand[1];
1440
                                                                returnValue[1:0]<=returnValue[3:2];
1441
                                                        end
1442
                                                endcase
1443
                                        end else begin
1444
                                                phase<=0;
1445
                                        end
1446
                                end
1447
                                // branch to abbrev
1448
                                6: begin
1449
                                        address<='h18;
1450
                                        phase<=phase+1;
1451
                                        temp<=address;
1452
                                        operand[0]<=delayedValue;
1453
                                        returnValue[3:2]=returnValue[1:0];
1454
                                        returnValue[1:0]=`PRINTEFFECT_ABBREVRET;
1455
                                end
1456
                                7: begin address<=address+1; operand[2][7:0]=data; phase<=phase+1; end
1457
                                8: begin address<=(operand[2][7:0]<<8)|data+2*store; phase<=phase+1; end
1458
                                9: begin address<=address+1; operand[2][7:0]<=data; phase<=phase+1; end
1459
                                default: begin address<=2*((operand[2][7:0]<<8)|data); phase<=0; end
1460
                        endcase
1461
`else
1462
                        if (data[7] || returnValue[1:0]!=`PRINTEFFECT_FETCHAFTER) begin
1463
                                if (returnValue[1:0]==`PRINTEFFECT_FETCHAFTER)
1464
                                        pc<=address+2;
1465
                                operand[0]<=`PRINT_CALLBACK;
1466
                                $display("Print from %h\n", temp);
1467
                                operand[1]<=temp[0]|((returnValue[1:0]==`PRINTEFFECT_RET1)?2:0); operand[2]<=temp[16:1];
1468
                                operTypes[1]=`OPER_LARGE; operTypes[2]=`OPER_LARGE;
1469
                                CallFunction(returnValue[1:0]==`PRINTEFFECT_RET1, 1);
1470
                        end else begin
1471
                                address<=address+2;
1472
                        end
1473
`endif
1474
                end
1475
`ifdef HARDWARE_PRINT
1476
                `STATE_PRINT_CHAR: begin
1477
                        address<=pc;
1478
                        printEnable<=0;
1479
                        state<=`STATE_FETCH_OP;
1480
                end
1481
`endif
1482
                default: begin
1483
                        $display("HALT");
1484
                        operand[1]<=(pc>>1);
1485
                        operand[2]<=operand[0];
1486
                        operand[3]<=operand[1];
1487
                        operand[0]<=`EXCEPTION_CALLBACK;
1488
                        //operTypes[0]<=`OPER_LARGE;
1489
                        operTypes[1]<=`OPER_LARGE;
1490
                        operTypes[2]<=`OPER_LARGE;
1491
                        operTypes[3]<=`OPER_LARGE;
1492
                        CallFunction(0,1);
1493
                end
1494
        endcase
1495
end
1496
 
1497
endmodule
1498
 
1499
module main();
1500
 
1501
reg clk;
1502
reg adcDout;
1503
reg reset;
1504
wire [7:0] data;
1505
wire [16:0] address;
1506
wire writeEnable;
1507
wire printEnable;
1508
wire romCS;
1509
wire ramCS;
1510
wire led0;
1511
wire led1;
1512
wire led2;
1513
wire lcdCS;
1514
wire lcdRS;
1515
wire lcdReset;
1516
wire adcCS;
1517
wire a17;
1518
wire a18;
1519
 
1520
integer file,readData,i,j,numOps,cycles,stateCycles[15:0],opCycles[255:0],ops[255:0];
1521
integer touch,touchX, touchY, touchZ;
1522
reg [7:0] mem [128*1024:0];
1523
reg [7:0] dynamicMem [128*1024:0];
1524
 
1525
assign data=(!romCS ? mem[address] : (!ramCS ? (!writeEnable ? 8'bZ : dynamicMem[address] ) : 8'bZ ) );
1526
 
1527
initial
1528
begin
1529
        $display("Welcome");
1530
        file=$fopen("rom.z3","rb");
1531
        readData=$fread(mem, file);
1532
        $display("File read:%h %d", file, readData);
1533
        $fclose(file);
1534
        touch=$fopen("touch.txt","r");
1535
        adcDout=0;
1536
        reset=1;
1537
        numOps=0;
1538
        cycles=0;
1539
        mem['h1E57F]=1; // Suppress game select screen as it's slow
1540
        for (i=0; i<16; i=i+1)
1541
                stateCycles[i]=0;
1542
        for (i=0; i<256; i=i+1) begin
1543
                opCycles[i]=0;
1544
                ops[i]=0;
1545
        end
1546
        //$monitor("%h %h %h State:%d(%d) Op:%h Num:%h OperType:%h%h%h%h OperIdx:%d Operand:%h %h Store:%h Branch:%h", clk, data, address, b.state, b.phase, b.op, b.operNum, b.operTypes[0], b.operTypes[1], b.operTypes[2], b.operTypes[3], b.operandIdx, b.operand[0], b.operand[1], b.store, b.branch);
1547
        for (i=0; i
1548
                clk=1;
1549
                #5 clk=0;
1550
                if (!ramCS && !writeEnable) begin
1551
                        dynamicMem[address]=data;
1552
                end
1553
`ifdef HARDWARE_PRINT
1554
                if (!printEnable) begin
1555
                        $display("PRINT: %c", data);
1556
                end
1557
`endif
1558
                if (b.state==`STATE_HALT) begin
1559
                        $display("Halt");
1560
                        i=10000000;
1561
                end
1562
                if (b.operNum==`OP_VAR && b.op==`OPVAR_GETTOUCH && b.phase==0 && b.state==`STATE_DO_OP) begin
1563
                        b.phase=3;
1564
                        if ($fscanf(touch, "%d %d %d", touchX, touchY, touchZ)==-1) begin
1565
                                i=10000000;
1566
                        end
1567
                        $display("Read: %d %d %d", touchX, touchY, touchZ);
1568
                        case (b.operand[0])
1569
                                'h93: b.operand[1]=touchZ;
1570
                                'h95: b.operand[1]=touchX;
1571
                                'h1A: b.operand[1]=touchY;
1572
                                default: begin $display("Bad touch"); $finish; end
1573
                        endcase
1574
                end
1575
                if (b.operNum==`OP_VAR && b.op==`OPVAR_BLIT1 && b.phase==0 && b.state==`STATE_DO_OP) begin
1576
                        b.operand[1]=1;
1577
                end
1578
                //if (b.curPC<'h1e000)
1579
                begin
1580
                        if (b.state==`STATE_FETCH_OP) begin
1581
                                ops[b.op+(32*b.operNum)]=ops[b.op+(32*b.operNum)]+1;
1582
                                numOps=numOps+1;
1583
                        end
1584
                        if (b.state!=`STATE_RESET) begin
1585
                                cycles=cycles+1;
1586
                                opCycles[b.op+(32*b.operNum)]=opCycles[b.op+(32*b.operNum)]+1;
1587
                        end
1588
                        stateCycles[b.state]=stateCycles[b.state]+1;
1589
                end
1590
                $display("Mem req: %h WE:%d PE:%d%d%d%d RoS:%d RaS:%d D:%h LEDs:%d%d%d ADC:%d%d%d%d%d%d%d Ops:%d/%d", address, !writeEnable, printEnable, lcdCS, lcdRS, lcdReset, !romCS, !ramCS, data, !led0, !led1, !led2, !adcCS, address[0], address[1], lcdRS, printEnable, data[7], data[6], numOps, cycles);
1591
        end
1592
        for (i=0; i<16; i=i+1)
1593
                if (stateCycles[i]>0)
1594
                        $display("State:%d %d", i, stateCycles[i]);
1595
        for (i=0; i<256; i=i+1)
1596
                if (opCycles[i]>0)
1597
                        $display("OpCyc:%d/%d %d/%d=%d", i/32, i%32, opCycles[i], ops[i], opCycles[i]/ops[i]);
1598
        file=$fopen("ram.dat", "wb");
1599
        for (i=0; i<'h20000; i=i+16) begin
1600
                $fwrite(file, "%05h: ", i);
1601
                for (j=0; j<16; j=j+2)
1602
                        $fwrite(file, "%02x%02x ", dynamicMem[i+j][7:0], dynamicMem[i+j+1][7:0]);
1603
                for (j=0; j<16; j=j+1)
1604
                        $fwrite(file, "%c", (dynamicMem[i+j][7:0]>=32)?dynamicMem[i+j][7:0]:46);
1605
                $fwrite(file, "\n");
1606
        end
1607
        $fwrite(file, "\nBitmap:\n");
1608
        for (i='h1b500; i<'h20000; i=i+30) begin
1609
                for (j=0; j<30; j=j+1)
1610
                        $fwrite(file, "%d%d%d%d%d%d%d%d",
1611
                dynamicMem[i+j][7], dynamicMem[i+j][6],
1612
                dynamicMem[i+j][5], dynamicMem[i+j][4],
1613
                dynamicMem[i+j][3], dynamicMem[i+j][2],
1614
                dynamicMem[i+j][1], dynamicMem[i+j][0]);
1615
                $fwrite(file, "\n");
1616
        end
1617
        $fclose(file);
1618
        $fclose(touch);
1619
        $finish;
1620
end
1621
 
1622
boss b(clk, adcDout, reset, data, address, writeEnable, printEnable, romCS, ramCS, led0, led1, led2, lcdCS, lcdRS, lcdReset, adcCS, a17, a18);
1623
 
1624
endmodule
1625
 

powered by: WebSVN 2.1.0

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