URL
https://opencores.org/ocsvn/z3/z3/trunk
Subversion Repositories z3
[/] [z3/] [trunk/] [z3.vl] - Rev 2
Compare with Previous | Blame | View Log
module boss(clk, adcDout, reset, data, waddress, we, pe, romCS, ramCS, led0, led1, led2, lcdCS, lcdRS, lcdReset, nadcCS, a17, a18);input clk;input adcDout;input reset;inout [7:0] data;output [16:0] waddress;output we;output pe;output romCS;output ramCS;output led0;output led1;output led2;output lcdCS;output lcdRS;output lcdReset;output nadcCS;output a17;output a18;reg [16:0] address;reg [7:0] dataOut;reg printEnable;reg writeEnable;reg rlcdRS;reg rlcdReset;reg adcCS;reg a17;reg a18;wire [16:0] waddress;wire we;wire pe;wire romCS;wire ramCS;wire led0;wire led1;wire led2;wire lcdCS;wire lcdRS;wire lcdReset;wire nadcCS;//`define HARDWARE_PRINT//`define REAL_HARDWARE`define CALLBACK_BASE 'h1E58B`define INIT_CALLBACK 'h0`define PRINT_CALLBACK 'h1`define PRINTCHAR_CALLBACK 'h2`define PRINTNUM_CALLBACK 'h3`define READ_CALLBACK 'h4`define STATUS_CALLBACK 'h5`define QUIT_CALLBACK 'h6`define EXCEPTION_CALLBACK 'h7`define OPER_LARGE 2'b00`define OPER_SMALL 2'b01`define OPER_VARI 2'b10`define OPER_OMIT 2'b11`define STATE_RESET 0`define STATE_FETCH_OP 1`define STATE_READ_TYPES 2`define STATE_READ_OPERS 3`define STATE_READ_INDIRECT 4`define STATE_READ_STORE 5`define STATE_READ_BRANCH 6`define STATE_DO_OP 7`define STATE_READ_FUNCTION 8`define STATE_CALL_FUNCTION 9`define STATE_RET_FUNCTION 10`define STATE_STORE_REGISTER 11`define STATE_PRINT 12`define STATE_DIVIDE 13`define STATE_HALT 14`define STATE_PRINT_CHAR 15`define OP_0 2'b00`define OP_1 2'b01`define OP_2 2'b10`define OP_VAR 2'b11`define OP0_RTRUE 'h0`define OP0_RFALSE 'h1`define OP0_PRINT 'h2`define OP0_PRINTRET 'h3`define OP0_NOP 'h4`define OP0_SAVE 'h5`define OP0_RESTORE 'h6`define OP0_RESTART 'h7`define OP0_RETPOP 'h8`define OP0_POP 'h9`define OP0_QUIT 'hA`define OP0_NEWLINE 'hB`define OP0_SHOWSTATUS 'hC`define OP0_VERIFY 'hD`define OP0_DYNAMIC 'hF`define OP1_JZ 'h0`define OP1_GETSIBLING 'h1`define OP1_GETCHILD 'h2`define OP1_GETPARENT 'h3`define OP1_GETPROPLEN 'h4`define OP1_INC 'h5`define OP1_DEC 'h6`define OP1_PRINTADDR 'h7`define OP1_SWITCHBANK 'h8`define OP1_REMOVEOBJ 'h9`define OP1_PRINTOBJ 'hA`define OP1_RET 'hB`define OP1_JUMP 'hC`define OP1_PRINTPADDR 'hD`define OP1_LOAD 'hE`define OP1_NOT 'hF`define OP2_JE 'h1`define OP2_JL 'h2`define OP2_JG 'h3`define OP2_DEC_CHK 'h4`define OP2_INC_CHK 'h5`define OP2_JIN 'h6`define OP2_TEST 'h7`define OP2_OR 'h8`define OP2_AND 'h9`define OP2_TESTATTR 'hA`define OP2_SETATTR 'hB`define OP2_CLEARATTR 'hC`define OP2_STORE 'hD`define OP2_INSERTOBJ 'hE`define OP2_LOADW 'hF`define OP2_LOADB 'h10`define OP2_GETPROP 'h11`define OP2_GETPROPADDR 'h12`define OP2_GETNEXTPROP 'h13`define OP2_ADD 'h14`define OP2_SUB 'h15`define OP2_MUL 'h16`define OP2_DIV 'h17`define OP2_MOD 'h18`define OP2_WRITEREG 'h1E`define OPVAR_CALL 'h0`define OPVAR_STOREW 'h1`define OPVAR_STOREB 'h2`define OPVAR_PUTPROP 'h3`define OPVAR_SREAD 'h4`define OPVAR_PRINTCHAR 'h5`define OPVAR_PRINTNUM 'h6`define OPVAR_RANDOM 'h7`define OPVAR_PUSH 'h8`define OPVAR_PULL 'h9`define OPVAR_GETTOUCH 'h1E`define OPVAR_BLIT1 'h1F`define PRINTEFFECT_FETCH 0`define PRINTEFFECT_FETCHAFTER 1`define PRINTEFFECT_RET1 2`define PRINTEFFECT_ABBREVRET 3reg forceStaticRead;reg forceDynamicRead;reg [3:0] state;reg [3:0] phase;reg [16:0] pc;reg [16:0] curPC;reg [15:0] globalsAddress;reg [15:0] objectTable;reg readHigh;reg [4:0] op;reg [1:0] operNum;reg [1:0] operTypes [4:0];reg [15:0] operand [3:0];reg [2:0] operandIdx;reg [13:0] branch;reg [7:0] store;reg negate;reg delayedBranch;reg divideAddOne;reg [15:0] returnValue;reg [6:0] opsToRead;reg [6:0] currentLocal;reg [16:0] csStack;reg [15:0] stackAddress;reg [16:0] temp;reg [15:0] random;reg [1:0] alphabet;reg [1:0] long;reg nextLoadIsDynamic;reg lastWriteWasDraw;reg adcClk;reg adcDin;reg [7:0] cachedReg;reg [15:0] cachedValue;// xp<=adcConfig[0]?0:'bZ;// yp<=adcConfig[1]?1:'bZ;// xm<=adcConfig[2]?1:'bZ;// ym<=adcConfig[3]?0:'bZ;// XP dataOut[6]// XM lcsRS// YP dataOut[7]// YM lcdWRinitialbeginstate=`STATE_RESET;forceDynamicRead=0;forceStaticRead=0;writeEnable=0;printEnable=0;phase=0;readHigh=0;nextLoadIsDynamic=0;adcCS=0;a17=0;a18=0;cachedReg=0;cachedValue=0;lastWriteWasDraw=0;endassign waddress[16:2] = address[16:2];assign waddress[0] = adcCS?adcClk:address[0];assign waddress[1] = adcCS?adcDin:address[1];assign data[5:0] = (writeEnable || printEnable)?dataOut[5:0]:6'bZ;assign data[6] = (writeEnable || printEnable)?dataOut[6]:((adcCS && operand[0][0])?0:'bZ);assign data[7] = (writeEnable || printEnable)?dataOut[7]:((adcCS && operand[0][1])?1:'bZ);assign romCS = !(!adcCS && !printEnable && !writeEnable && !forceDynamicRead && (forceStaticRead || address[16]==1));assign ramCS = !(!adcCS && !printEnable && (writeEnable || forceDynamicRead || (!forceStaticRead && address[16]==0)));assign pe = adcCS?(operand[0][3]?0:'bZ):(!printEnable || !clk);assign we = !writeEnable;assign led0 = !address[12];assign led1 = !address[13];assign led2 = !address[14];assign lcdCS = !printEnable || !clk;assign lcdRS = adcCS?(operand[0][2]?1:'bZ):rlcdRS;assign lcdReset = rlcdReset;assign nadcCS = !adcCS;task StoreB;beginif (phase==0) begincachedReg<=15; nextLoadIsDynamic<=0; address<=operand[0]+operand[1]; writeEnable<=1; dataOut<=operand[2][7:0]; phase<=phase+1;end else beginaddress<=pc; writeEnable<=0; state<=`STATE_FETCH_OP;endendendtasktask StoreW;begincase (phase)0: begin cachedReg<=15; nextLoadIsDynamic<=0; address<=operand[0]+operand[1]*2; writeEnable<=1; dataOut<=operand[2][15:8]; phase<=phase+1; end1: begin address<=address+1; dataOut<=operand[2][7:0]; phase<=phase+1; enddefault: begin address<=pc; writeEnable<=0; state<=`STATE_FETCH_OP; endendcaseendendtasktask StoreRegisterAndBranch;input [7:0] regNum;input [15:0] value;input doBranch;beginstate<=`STATE_STORE_REGISTER;store<=regNum;returnValue<=value;delayedBranch<=doBranch;phase<=0;endendtasktask StoreResultAndBranch;input [15:0] result;input doBranch;beginif (store>=16) beginaddress<=globalsAddress+2*(store-16);end else if (store==0) beginaddress<=2*stackAddress;stackAddress<=stackAddress+1;end else beginaddress<=csStack+8+2*(store-1);enddataOut<=result[15:8];writeEnable<=1;state<=`STATE_STORE_REGISTER;returnValue[7:0]<=result[7:0];delayedBranch<=doBranch;phase<=1;endendtasktask StoreResult;input [15:0] result;beginStoreResultAndBranch(result, negate); // negate means won't branchendendtasktask StoreResultSlow;input [15:0] result;beginStoreRegisterAndBranch(store, result, negate); // negate means won't branchendendtasktask ReturnFunction;input [15:0] value;beginreturnValue<=value;phase<=0;state<=`STATE_RET_FUNCTION;endendtasktask CallFunction;input doubleReturn;input noStoreOnReturn;beginnegate<=doubleReturn;delayedBranch<=noStoreOnReturn;phase<=0;state<=`STATE_CALL_FUNCTION;endendtasktask DoBranch;input result;beginif ((!result)==negate) beginif (branch==0) beginReturnFunction(0);end else if (branch==1) beginReturnFunction(1);end else beginpc<=$signed(pc)+$signed(branch)-2;address<=$signed(pc)+$signed(branch)-2;state<=`STATE_FETCH_OP;endend else beginaddress<=pc;state<=`STATE_FETCH_OP;endendendtasktask LoadAndStore;input [16:0] loadAddress;input word;beginif (phase==0) beginstore<=data;forceDynamicRead<=nextLoadIsDynamic;nextLoadIsDynamic<=0;address<=loadAddress;temp[7:0]<=0;phase<=word?phase+1:2;end else if (phase==1) begintemp[7:0]<=data;address<=address+1;phase<=phase+1;end else beginforceDynamicRead<=0;StoreResultSlow((temp[7:0]<<8)|data);endendendtaskfunction [16:0] GetObjectAddr;input [7:0] object;beginGetObjectAddr=objectTable+2*31+9*(object-1);endendfunctiontask TestAttr;beginif (phase==0) beginaddress<=GetObjectAddr(operand[0])+(operand[1]/8); phase<=phase+1;end else beginDoBranch(data[7-(operand[1]&7)]);endendendtasktask SetAttr;begincase (phase)0: begin address<=GetObjectAddr(operand[0])+(operand[1]/8); phase<=phase+1; end1: begin dataOut<=data|(1<<(7-(operand[1]&7))); writeEnable<=1; phase<=phase+1; enddefault: begin writeEnable<=0; address<=pc; state=`STATE_FETCH_OP; endendcaseendendtasktask ClearAttr;begincase (phase)0: begin address<=GetObjectAddr(operand[0])+(operand[1]/8); phase<=phase+1; end1: begin dataOut<=data&(~(1<<(7-(operand[1]&7)))); writeEnable<=1; phase<=phase+1; enddefault: begin writeEnable<=0; address<=pc; state=`STATE_FETCH_OP; endendcaseendendtasktask JumpIfParent;beginif (phase==0) beginaddress<=GetObjectAddr(operand[0])+4; phase<=phase+1;end else beginDoBranch(operand[1]==data);endendendtasktask GetRelative;input [1:0] offset;input branch;beginif (phase==0) beginaddress<=GetObjectAddr(operand[0])+4+offset; phase<=phase+1;end else beginStoreResultAndBranch(data, branch?data!=0:negate);endendendtasktask FindProp;begincase (phase[2:0])0: begin store<=data; address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end1: begin temp[16]<=0; temp[15:8]<=data; temp[7:0]<=0; address<=address+1; phase<=phase+1; end2: begin address<=temp|data; phase<=phase+1; end3: begin address<=address+2*data+1; phase<=phase+1; end4: beginif (data==0) begin // end of search (get default)address<=objectTable+2*(operand[1]-1);phase<=phase+1;end else if (data[4:0]==operand[1]) begin // found propertyaddress<=address+1;if (data[7:5]==0) // only 1 bytephase<=6;elsephase<=5;end else begin // skip over dataaddress<=address+data[7:5]+2;endend5: begin temp[7:0]<=data; address<=address+1; phase<=phase+1; enddefault: begin StoreResultSlow((temp[7:0]<<8)|data); endendcaseendendtasktask SetProp;begincase (phase[2:0])0: begin address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end1: begin temp[16]<=0; temp[15:8]<=data; temp[7:0]<=0; address<=address+1; phase<=phase+1; end2: begin address<=temp|data; phase<=phase+1; end3: begin address<=address+2*data+1; phase<=phase+1; end4: begin`ifndef REAL_HARDWAREif (data==0) begin // end of searchstate<=`STATE_HALT;end else`endifif (data[4:0]==operand[1]) begin // found propertyif (data[7:5]==0) begin // only 1 bytedataOut<=operand[2][7:0];phase<=6;address<=address+1;writeEnable<=1;end else begindataOut<=operand[2][15:8];phase<=5;address<=address+1;writeEnable<=1;endend else begin // skip over dataaddress<=address+data[7:5]+2;endend5: begin dataOut<=operand[2][7:0]; address<=address+1; phase<=phase+1; enddefault: begin state<=`STATE_FETCH_OP; address<=pc; writeEnable<=0; endendcaseendendtasktask FindPropAddrLen;begincase (phase[2:0])0: begin store<=data; address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end1: begin temp[16]<=0; temp[15:8]<=data; temp[7:0]<=0; address<=address+1; phase<=phase+1; end2: begin address<=temp|data; phase<=phase+1; end3: begin address<=address+2*data+1; phase<=phase+1; enddefault: beginif (data==0) begin // end of searchStoreResultSlow(0);end else if (data[4:0]==operand[1]) begin // found propertyStoreResultSlow(address+1);end else begin // skip over dataaddress<=address+data[7:5]+2;endendendcaseendendtasktask FindNextProp;begincase (phase[2:0])0: begin store<=data; address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end1: begin temp[16]<=0; temp[15:8]<=data; temp[7:0]<=0; address<=address+1; phase<=phase+1; end2: begin address<=temp|data; phase<=phase+1; end3: begin address<=address+2*data+1; phase<=phase+1; enddefault: beginif (operand[1]==0)StoreResultSlow(data[4:0]);`ifndef REAL_HARDWAREelse if (data==0) // end of searchstate<=`STATE_HALT;`endifelse begin // skip over dataif (data[4:0]==operand[1])operand[1]<=0;address<=address+data[7:5]+2;endendendcaseendendtasktask GetPropLen;beginif (phase==0) beginaddress<=operand[0]-1; phase<=phase+1;end else beginStoreResultSlow((operand[0]==0)?0:(data[7:5]+1));endendendtasktask Pull;input return;begincase (phase)0: beginaddress<=2*(stackAddress-1);forceDynamicRead<=1;phase<=phase+1;end1: begintemp[7:0]<=data;stackAddress<=address>>1;address<=address+1;phase<=phase+1;enddefault: beginforceDynamicRead<=0;if (return) beginReturnFunction((temp[7:0]<<8)|data);end else beginif (operand[0]==0)stackAddress<=stackAddress-1;StoreRegisterAndBranch(operand[0], (temp[7:0]<<8)|data, negate);endendendcaseendendtasktask Print;input [16:0] addr;input [1:0] effect;begintemp<=addr;state<=`STATE_PRINT;returnValue[1:0]<=effect;delayedBranch<=0;phase<=0;endendtasktask PrintObj;begincase (phase[1:0])0: begin address<=GetObjectAddr(operand[0])+7; phase<=phase+1; end1: begin store<=data; address<=address+1; phase<=phase+1; enddefault: Print((store<<8)+data+1, `PRINTEFFECT_FETCH);endcaseendendtasktask RemoveObject;begincase (phase[3:0])0: begin address<=GetObjectAddr(operand[0])+4; /*obj.parent*/ phase<=phase+1; end1: beginif (data==0) beginphase<=(operand[1]!=0)?6:9;end else beginphase<=phase+1;endtemp[15:8]<=data;writeEnable<=1;dataOut<=operand[1];end2: begin writeEnable<=0; address<=address+1; /*obj.sibling*/ phase<=phase+1; end3: begin temp[7:0]<=data; writeEnable<=1; dataOut<=0; phase<=phase+1; end4: begin writeEnable<=0; address<=GetObjectAddr(temp[15:8])+6; /*parent.child*/ phase<=phase+1; end5: beginif (data==operand[0]) begin // found objectdataOut<=temp[7:0];writeEnable<=1;phase<=(operand[1]!=0)?phase+1:9;end else beginaddress<=GetObjectAddr(data)+5; /*follow sibling*/endend6: begin address<=GetObjectAddr(operand[1])+6; writeEnable<=0; phase<=phase+1; end7: begin temp[7:0]<=data; writeEnable<=1; dataOut<=operand[0]; phase<=phase+1; end8: begin address<=GetObjectAddr(operand[0])+5; dataOut<=temp[7:0]; phase<=phase+1; enddefault: beginwriteEnable<=0;state<=`STATE_FETCH_OP;address<=pc;endendcaseendendtasktask Random;begincase (phase)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; end1: begin random<=random^(random>>9); phase<=phase+1; end2: begin random<=random^(random<<7); phase<=phase+1; enddefault: begin state<=`STATE_DIVIDE; delayedBranch<=1; divideAddOne<=1; operand[1]<=operand[0]; operand[0]<=random&'h7FFF; phase<=0; endendcaseendendtasktask PrintNum;begin`ifdef HARDWARE_PRINTcase (phase)0: begin negate<=0; operand[1]<=1; operand[2][2:0]<=2; operand[3][3:0]<=0; phase<=phase+1; end1,2,3,4: begin operand[1]<=(operand[1]<<3)+(operand[1]<<1); printEnable<=0; phase<=phase+1; end5: beginif (operand[0]>=operand[1]) beginoperand[0]<=operand[0]-operand[1];operand[3][3:0]<=operand[3][3:0]+1;negate<=1;printEnable<=0;end else beginprintEnable<=negate;dataOut<=operand[3][3:0]+48;operand[3][3:0]<=0;operand[1]<=1;operand[2][2:0]<=operand[2][2:0]+1;phase<=operand[2][2:0];endenddefault: begin printEnable<=0; state<=`STATE_FETCH_OP; endendcase`elseoperand[0]<=`PRINTNUM_CALLBACK;operand[1]<=operand[0];operTypes[1]<=`OPER_LARGE;CallFunction(0, 1);`endifendendtasktask PrintChar;input [7:0] char;begin$display("Print char: %d\n", char);`ifdef HARDWARE_PRINTprintEnable<=1;dataOut<=char;state<=`STATE_PRINT_CHAR;`elseoperand[0]<=`PRINTCHAR_CALLBACK;operand[1]<=char;operTypes[1]<=`OPER_LARGE;CallFunction(0, 1);`endifendendtasktask SRead;beginoperand[0]<=`READ_CALLBACK;operand[2]<=operand[0]; // Am swapping arguments just to save space on FPGAoperTypes[2]<=`OPER_LARGE;CallFunction(0, 1);endendtasktask WriteReg;begincase (phase)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 end1: begin dataOut<=operand[0][15:8]; printEnable<=1; phase<=phase+1; end2: begin dataOut<=operand[0][7:0]; if (operand[0]==0) phase<=4; else phase<=phase+1; end3: begin rlcdRS<=1; printEnable<=0; phase<=phase+1; end4: begin dataOut<=operand[1][15:8]; printEnable<=1; phase<=phase+1; end5: begin dataOut<=operand[1][7:0]; phase<=phase+1; enddefault: begin printEnable<=0; address<=pc; state<=`STATE_FETCH_OP; endendcaseendendtasktask Blit1;begincase (phase)0: begin forceDynamicRead<=1; rlcdRS<=0; phase<=phase+1; end1: begin dataOut<=0; printEnable<=1; phase<=phase+1; end2: begin address<=operand[0]*2; dataOut<=34; returnValue<=0; phase<=phase+1; end3: beginrlcdRS<=1;printEnable<=0;if (operand[1]==0) beginforceDynamicRead<=0;address<=pc;state<=`STATE_FETCH_OP;endphase<=phase+1;end4: beginstore<=data;dataOut<=data[7]?operand[3][15:8]:operand[2][15:8];printEnable<=1;phase<=6;end5: begindataOut<=store[7]?operand[3][15:8]:operand[2][15:8];printEnable<=1;phase<=phase+1;enddefault: begindataOut<=store[7]?operand[3][7:0]:operand[2][7:0];store[7:1]=store[6:0];returnValue<=returnValue+1;if (returnValue[2:0]==7) beginoperand[1]=operand[1]-1;phase<=3;address<=address+1;end else beginphase<=5;endendendcaseendendtasktask GetTouch;begincase (phase)0: beginadcCS<=1;adcClk<=0;adcDin<=1;operand[1]<='hffff;operand[2]<=1;phase<=1;end1: beginoperand[2][3:0]<=operand[2][3:0]+1;if (operand[2][3:0]==0) begin // Max clock rate for ADC is ~ 1MHz so divide our clock by 16adcClk<=1;operand[1]<=(operand[1]<<1)+adcDout;phase<=(!operand[1][9])?3:2;endend2: beginoperand[2][3:0]<=operand[2][3:0]+1;if (operand[2][3:0]==0) begin // Max clock rate for ADC is ~ 1MHz so divide our clock by 16operand[0][8:4]<=(operand[0][8:4]>>1);adcDin<=operand[0][4];adcClk<=0;phase<=1;endenddefault: begin adcCS<=0; StoreResultSlow(operand[1]&'h3FF); endendcaseendendtasktask DoOp;begincase (operNum)`OP_0: beginif (phase==0)$display("PC:%h Doing op0:%d Store:%h Branch:%h/%d", curPC, op, operand[0], store, branch, negate);case (op[3:0])`OP0_RTRUE: ReturnFunction(1);`OP0_RFALSE: ReturnFunction(0);`OP0_PRINT: Print(pc, `PRINTEFFECT_FETCHAFTER);`OP0_PRINTRET: Print(pc, `PRINTEFFECT_RET1);`OP0_SAVE,`OP0_RESTORE: DoBranch(0);`OP0_RESTART: state<=`STATE_RESET;`OP0_RETPOP: Pull(1);`OP0_QUIT: begin operand[0]<=`QUIT_CALLBACK; CallFunction(0,1); end`OP0_NEWLINE: PrintChar(10);`OP0_SHOWSTATUS: begin operand[0]<=`STATUS_CALLBACK; CallFunction(0,1); end`OP0_VERIFY: DoBranch(1);default: state<=`STATE_HALT;endcaseend`OP_1: beginif (phase==0)$display("PC:%h Doing op1:%d Operands:%h Store:%h Branch:%h/%d", curPC, op, operand[0], store, branch, negate);case (op[3:0])`OP1_JZ: DoBranch(operand[0]==0);`OP1_GETSIBLING: GetRelative(1,1);`OP1_GETCHILD: GetRelative(2,1);`OP1_GETPARENT: GetRelative(0,0);`OP1_GETPROPLEN: GetPropLen();`OP1_INC: StoreResult(operand[0]+1);`OP1_DEC: StoreResult(operand[0]-1);`OP1_PRINTADDR: Print(operand[0], `PRINTEFFECT_FETCH);`OP1_SWITCHBANK: begin a17<=operand[0][0]; a18<=operand[0][1]; state<=`STATE_RESET; end`OP1_REMOVEOBJ: begin operNum<=`OP_2; op<=`OP2_INSERTOBJ; operand[1]<=0; end`OP1_PRINTOBJ: PrintObj();`OP1_RET: ReturnFunction(operand[0]);`OP1_JUMP: begin pc<=$signed(pc)+$signed(operand[0])-2; address<=$signed(pc)+$signed(operand[0])-2; state<=`STATE_FETCH_OP; end`OP1_PRINTPADDR: Print(2*operand[0], `PRINTEFFECT_FETCH);`OP1_LOAD: StoreResult(operand[0]);`OP1_NOT: StoreResult(~operand[0]);default: state<=`STATE_HALT;endcaseend`OP_2: beginif (phase==0)$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));case (op)`OP2_JE: DoBranch(operand[0]==operand[1] || (operTypes[2]!=`OPER_OMIT && operand[0]==operand[2]) || (operTypes[3]!=`OPER_OMIT && operand[0]==operand[3]));`OP2_JL: DoBranch($signed(operand[0])<$signed(operand[1]));`OP2_JG: DoBranch($signed(operand[0])>$signed(operand[1]));`OP2_INC_CHK: StoreResultAndBranch(operand[0]+1, $signed(operand[0])+1>$signed(operand[1]));`OP2_DEC_CHK: StoreResultAndBranch(operand[0]-1, $signed(operand[0])-1<$signed(operand[1]));`OP2_JIN: JumpIfParent();`OP2_TEST: DoBranch((operand[0]&operand[1])==operand[1]);`OP2_OR: StoreResult(operand[0]|operand[1]);`OP2_AND: StoreResult(operand[0]&operand[1]);`OP2_TESTATTR: TestAttr();`OP2_SETATTR: SetAttr();`OP2_CLEARATTR: ClearAttr();`OP2_STORE: begin if (operand[0]==0) stackAddress<=stackAddress-1; StoreRegisterAndBranch(operand[0], operand[1], negate); end`OP2_INSERTOBJ: RemoveObject();`OP2_LOADW: LoadAndStore(operand[0]+2*operand[1], 1);`OP2_LOADB: LoadAndStore(operand[0]+operand[1], 0);`OP2_GETPROP: FindProp();`OP2_GETPROPADDR: FindPropAddrLen();`OP2_GETNEXTPROP: FindNextProp();`OP2_ADD: StoreResult($signed(operand[0])+$signed(operand[1]));`OP2_SUB: StoreResult($signed(operand[0])-$signed(operand[1]));`OP2_MUL: StoreResult($signed(operand[0])*$signed(operand[1]));`OP2_DIV: begin store<=data; state=`STATE_DIVIDE; delayedBranch<=0; divideAddOne<=0; end`OP2_MOD: begin store<=data; state=`STATE_DIVIDE; delayedBranch<=1; divideAddOne<=0; end`OP2_WRITEREG: WriteReg();default: state<=`STATE_HALT;endcaseenddefault: begin // 'OP_VARif (phase==0) beginif (operTypes[0]==`OPER_OMIT)$display("PC:%h Doing opvar:%d Operands: Store:%h Branch:%h/%d/%h", curPC, op, store, branch, negate, $signed(pc)+$signed(branch-2));else if (operTypes[1]==`OPER_OMIT)$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));else if (operTypes[2]==`OPER_OMIT)$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));else if (operTypes[3]==`OPER_OMIT)$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));else$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));endcase (op)`OPVAR_CALL: if (operand[0]==0) StoreResultSlow(0); else CallFunction(0, 0);`OPVAR_STOREW: StoreW();`OPVAR_STOREB: StoreB();`OPVAR_PUTPROP: SetProp();`OPVAR_SREAD: SRead();`OPVAR_PRINTCHAR: PrintChar(operand[0]);`OPVAR_PRINTNUM: PrintNum();`OPVAR_RANDOM: Random();`OPVAR_PUSH: StoreRegisterAndBranch(0, operand[0], negate);`OPVAR_PULL: Pull(0);`OPVAR_GETTOUCH: GetTouch();`OPVAR_BLIT1: Blit1();default: state<=`STATE_HALT;endcaseendendcaseendendtask`ifdef HARDWARE_PRINTtask DoPrint;input [4:0] char;beginif (delayedBranch) beginstore[4:0]<=char;operand[1]<=phase+1;delayedBranch<=0;phase<=6;end else if (long==1) beginoperand[3][4:0]=char;long<=long+1;end else if (long==2) beginprintEnable<=1;dataOut<=(operand[3][4:0]<<5)|char;long<=0;end else beginphase<=phase+1;if (char==0) beginprintEnable<=1;dataOut<=32;end else if (char==4 || char==5) beginprintEnable<=0;alphabet=char-3;end else if (char>=6) beginprintEnable<=!(alphabet==2 && char==6);if (alphabet==2) begincase (char)6: long<=1;7: dataOut<=10;8,9,10,11,12,13,14,15,16,17: dataOut<=char-8+48;18: dataOut<=46;19: dataOut<=44;20: dataOut<=33;21: dataOut<=63;22: dataOut<=95;23: dataOut<=35;24: dataOut<=39;25: dataOut<=34;26: dataOut<=47;27: dataOut<=92;28: dataOut<=45;29: dataOut<=58;30: dataOut<=40;31: dataOut<=41;endcaseend else begindataOut<=char-6+((alphabet==0)?97:65);endalphabet<=0;end else beginprintEnable<=0;store[7:5]<=(char-1);delayedBranch<=1;endendendendtask`endiftask FinishReadingOps;begincase (operNum)`OP_1: begincase (op[3:0])`OP1_INC, `OP1_DEC, `OP1_LOAD: state<=`STATE_READ_INDIRECT;`OP1_GETSIBLING,`OP1_GETCHILD,`OP1_GETPARENT,`OP1_GETPROPLEN,`OP1_NOT: state<=`STATE_READ_STORE;`OP1_JZ: state<=`STATE_READ_BRANCH;default: state<=`STATE_DO_OP;endcasepc<=pc+1;end`OP_2: begincase (op[4:0])`OP2_INC_CHK,`OP2_DEC_CHK: begin pc<=pc+1; state<=`STATE_READ_INDIRECT; end`OP2_OR,`OP2_AND,`OP2_ADD,`OP2_SUB,`OP2_MUL: begin pc<=pc+1; state<=`STATE_READ_STORE; end`OP2_LOADW,`OP2_LOADB,`OP2_GETPROP ,`OP2_GETPROPADDR,`OP2_GETNEXTPROP,`OP2_DIV,`OP2_MOD: begin pc<=pc+2; state<=`STATE_DO_OP; end`OP2_JE,`OP2_JL,`OP2_JG,`OP2_JIN,`OP2_TEST,`OP2_TESTATTR: begin pc<=pc+1; state<=`STATE_READ_BRANCH; enddefault: begin pc<=pc+1; state<=`STATE_DO_OP; endendcaseenddefault: begin // `OP_VARpc<=pc+1;case (op[4:0])`OPVAR_CALL,`OPVAR_RANDOM,`OPVAR_GETTOUCH: state<=`STATE_READ_STORE;default: state<=`STATE_DO_OP;endcaseendendcaseendendtaskalways @ (posedge clk)begincase(state)`STATE_RESET: begincase (phase)0: begin printEnable<=0; random<=1; forceStaticRead<=1; address<='h6; phase<=phase+1; end1: begin address<='h7; phase<=phase+1; pc[15:8]<=data; pc[16]<=0; end2: begin address<='hA; phase<=phase+1; pc[7:0]<=data; end3: begin address<='hB; phase<=phase+1; objectTable[15:8]<=data; end4: begin address<='hC; phase<=phase+1; objectTable[7:0]<=data; end5: begin address<='hD; phase<=phase+1; globalsAddress[15:8]<=data; end6: begin address<=0; phase<=phase+1; globalsAddress[7:0]<=data; end7: begin dataOut<=data; writeEnable<=1; phase<=8; end8: begin writeEnable<=0; address<=address+1; if (address[15:0]=='hffff) phase<=9; else phase<=7; end9: begin writeEnable<=1; dataOut<=0; address<=address+1; if (address[15:0]=='hffff) begin writeEnable<=0; phase<=10; end end10: begin rlcdReset<=address[10]; rlcdRS<=1; printEnable<=0; address<=address+1; if (address[10:0]=='h7ff) phase<=11; enddefault: begincachedReg<=15;address<=pc;forceStaticRead<=0;stackAddress<=64*1024/2;csStack<=65*1024;operand[0]<=`INIT_CALLBACK;operTypes[1]<=`OPER_OMIT;CallFunction(0, 1);endendcaseend`STATE_CALL_FUNCTION: begincase (phase)0: begin $display("Call function %h", operand[0]*2); address<=csStack; writeEnable<=1; dataOut<=(delayedBranch<<2)|(negate<<1)|pc[16]; phase<=phase+1; end1: begin address<=address+1; dataOut<=pc[15:8]; phase<=phase+1; end2: begin address<=address+1; dataOut<=pc[7:0]; phase<=4; end3: begin end // pointless phase but for some reason saves gates4: begin address<=address+1; dataOut<=stackAddress[15:8]; phase<=phase+1; end5: begin address<=address+1; dataOut<=stackAddress[7:0]; phase<=phase+1; end6: begin address<=address+1; dataOut<=store; phase<=(operand[0][15:3]==0)?phase+1:10; end7: begin address<=`CALLBACK_BASE+5*(operand[0]&7); writeEnable<=0; phase<=phase+1; end8: begin address<=address+1; operand[0][15:8]<=data; phase<=phase+1; end9: begin operand[0][7:0]<=data; phase<=phase+1; enddefault: begincachedReg<=15;csStack<=csStack+38;address<=2*operand[0];state<=`STATE_READ_FUNCTION;writeEnable<=0;phase<=0;endendcaseend`STATE_RET_FUNCTION: begincase (phase)0: begin csStack<=csStack-38; address<=csStack-38; forceDynamicRead<=1; phase<=phase+1; end1: begin pc[16]<=data[0]; negate<=data[1]; delayedBranch<=data[2]; address<=address+1; phase<=phase+1; end2: begin pc[15:8]<=data; address<=address+1; phase<=phase+1; end3: begin pc[7:0]<=data; address<=address+1; phase<=phase+1; end4: begin stackAddress[15:8]<=data; address<=address+1; phase<=phase+1; end5: begin stackAddress[7:0]<=data; address<=address+1; phase<=phase+1; enddefault: beginforceDynamicRead<=0;cachedReg<=15;if (negate) beginphase<=0;end else if (delayedBranch) beginstate<=`STATE_FETCH_OP;address<=pc;end else beginStoreRegisterAndBranch(data, returnValue, negate);endendendcaseend`STATE_READ_FUNCTION: begincase (phase)0: beginif (data==0) beginstate<=`STATE_FETCH_OP;end else beginopsToRead<=4*data-1;phase<=phase+1;endcurrentLocal<=0;pc<=address+1;address<=address+1;enddefault: beginif (opsToRead&1) beginif (currentLocal<6 && operTypes[(currentLocal>>1)+1]!=`OPER_OMIT) begindataOut<=currentLocal[0]?operand[(currentLocal>>1)+1][7:0]:operand[(currentLocal>>1)+1][15:8];end else begindataOut<=data;endaddress<=csStack+8+currentLocal;writeEnable<=1;currentLocal<=currentLocal+1;end else beginpc<=pc+1;address<=pc+1;writeEnable<=0;endif (opsToRead==0) beginstate<=`STATE_FETCH_OP;endopsToRead<=opsToRead-1;endendcaseend`STATE_FETCH_OP: beginphase<=0;operTypes[2]<=`OPER_OMIT;operTypes[3]<=`OPER_OMIT;operTypes[4]<=`OPER_OMIT;curPC<=pc;$display("Fetching op at %h", pc);if (!reset) beginstate<=`STATE_RESET;a17<=0;a18<=0;end else begincase (data[7:6])2'b10: begin// short formop[4:0]<=data[3:0];operTypes[0]<=data[5:4];operTypes[1]<=`OPER_OMIT;if (data[5:4]==2'b11) beginoperNum[1:0]<=`OP_0;case (data[3:0])`OP0_POP: begin cachedReg<=15; stackAddress<=stackAddress-1; end`OP0_NOP: begin /*nop*/ end`OP0_DYNAMIC: nextLoadIsDynamic<=1;`OP0_SAVE,`OP0_RESTORE,`OP0_VERIFY: state<=`STATE_READ_BRANCH;default: state<=`STATE_DO_OP;endcaseend else beginoperNum[1:0]<=`OP_1;state<=`STATE_READ_OPERS;endend2'b11: begin// variable formop[4:0]<=data[4:0];operNum[1:0]<=(data[5]?`OP_VAR:`OP_2);state<=`STATE_READ_TYPES;enddefault: begin// long formop[4:0]<=data[4:0];operNum[1:0]<=`OP_2;operTypes[0]<=(data[6] ? `OPER_VARI : `OPER_SMALL);operTypes[1]<=(data[5] ? `OPER_VARI : `OPER_SMALL);state<=`STATE_READ_OPERS;endendcaseendoperandIdx<=0;pc<=pc+1;address<=pc+1;end`STATE_READ_TYPES: beginoperTypes[0]<=data[7:6];operTypes[1]<=data[5:4];operTypes[2]<=data[3:2];operTypes[3]<=data[1:0];address<=pc+1;if (data[7:6]==`OPER_OMIT)FinishReadingOps();else beginstate<=`STATE_READ_OPERS;pc<=pc+1;endend`STATE_READ_OPERS: begincase (operTypes[operandIdx])`OPER_SMALL: beginoperand[operandIdx]<=data[7:0];address<=pc+1;operandIdx<=operandIdx+1;if (operTypes[operandIdx+1]==`OPER_OMIT)FinishReadingOps();elsepc<=pc+1;end`OPER_LARGE: beginaddress<=pc+1;if (!readHigh) beginoperand[operandIdx][15:8]<=data[7:0];readHigh<=1;pc<=pc+1;end else beginoperand[operandIdx][7:0]<=data[7:0];operandIdx<=operandIdx+1;readHigh<=0;if (operTypes[operandIdx+1]==`OPER_OMIT)FinishReadingOps();elsepc<=pc+1;endenddefault: begin // OPER_VARIcase (phase)0: beginif (data==0) beginstackAddress<=stackAddress-1;endif (cachedReg!=15 && data==cachedReg) beginoperand[operandIdx]<=cachedValue;address<=pc+1;operandIdx<=operandIdx+1;if (operTypes[operandIdx+1]==`OPER_OMIT)FinishReadingOps();elsepc<=pc+1;if (cachedReg==0)cachedReg<=15;end else beginif (data>=16) beginaddress<=globalsAddress+2*(data-16);end else if (data==0) beginaddress<=2*(stackAddress-1);end else beginaddress<=csStack+8+2*(data-1);endforceDynamicRead<=1;phase<=phase+1;endend1: beginoperand[operandIdx]<=(data<<8);address<=address+1;phase<=phase+1;enddefault: beginforceDynamicRead<=0;operand[operandIdx]<=operand[operandIdx]|data;address<=pc+1;operandIdx<=operandIdx+1;if (operTypes[operandIdx+1]==`OPER_OMIT)FinishReadingOps();elsepc<=pc+1;phase<=0;endendcaseendendcaseend`STATE_READ_INDIRECT: begincase (phase)0: begincachedReg<=15;store<=operand[0];if (operand[0]>=16) beginaddress<=globalsAddress+2*(operand[0]-16);end else if (operand[0]==0) beginif (op[4:0]!=`OP1_LOAD)stackAddress<=stackAddress-1;address<=2*(stackAddress-1);end else beginaddress<=csStack+8+2*(operand[0]-1);endforceDynamicRead<=1;phase<=phase+1;end1: beginoperand[0][15:8]<=data;address<=address+1;phase<=phase+1;enddefault: beginforceDynamicRead<=0;operand[0][7:0]<=data;if (op[4:0]==`OP1_LOAD)state<=`STATE_READ_STORE;else if (operNum==`OP_2)state<=`STATE_READ_BRANCH;elsestate<=`STATE_DO_OP;address<=pc;phase<=0;endendcaseend`STATE_READ_STORE: begincase (op[4:0])`OP1_GETSIBLING, `OP1_GETCHILD: state<=`STATE_READ_BRANCH;default: state<=`STATE_DO_OP;endcasestore<=data;pc<=pc+1;address<=pc+1;end`STATE_READ_BRANCH: beginif (!readHigh) beginif (data[6]) beginbranch<=data[5:0];negate<=!data[7];state<=`STATE_DO_OP;end else beginbranch[13:8]<=data[5:0];negate<=!data[7];readHigh<=1;endend else beginbranch[7:0]<=data;readHigh<=0;state<=`STATE_DO_OP;endpc<=pc+1;address<=pc+1;end`STATE_DO_OP: beginDoOp();end`STATE_STORE_REGISTER: begincase (phase)0: beginif (store>=16) beginaddress<=globalsAddress+2*(store-16);end else if (store==0) beginaddress<=2*stackAddress;stackAddress<=stackAddress+1;end else beginaddress<=csStack+8+2*(store-1);enddataOut<=returnValue[15:8];writeEnable<=1;phase<=phase+1;end1: begincachedReg<=store;cachedValue[15:8]<=dataOut;cachedValue[7:0]<=returnValue[7:0];dataOut<=returnValue[7:0];address<=address+1;phase<=phase+1;enddefault: beginDoBranch(delayedBranch);writeEnable<=0;phase<=0;endendcaseend`STATE_DIVIDE: begincase (phase)0: beginnegate<=operand[0][15]^operand[1][15];readHigh<=operand[0][15];if ($signed(operand[0])<0)operand[0]<=-operand[0];elseoperand[0]<=operand[0];`ifndef REAL_HARDWAREif (operand[1]==0)state=`STATE_HALT;else`endifif ($signed(operand[1])<0)operand[1]<=-operand[1];operand[2]<=1;operand[3]<=0;phase<=phase+1;end1: beginif (operand[1][15] || operand[0]<=operand[1]) beginphase<=phase+1;end else beginoperand[1]<=operand[1]<<1;operand[2]<=operand[2]<<1;endend2: beginif (operand[1]>operand[0]) beginif (operand[2]==1) beginif (negate) beginoperand[0]<=-operand[3];end else beginoperand[0]<=operand[3];endif (readHigh) beginoperand[1]<=-operand[0];end else beginoperand[1]<=operand[0];endreadHigh<=0;phase<=phase+1;end else beginoperand[1]<=operand[1]>>1;operand[2]<=operand[2]>>1;endend else beginoperand[0]<=operand[0]-operand[1];operand[3]<=operand[3]+operand[2];endenddefault: beginStoreResultSlow(delayedBranch?(operand[1]+divideAddOne):operand[0]);endendcaseend`STATE_PRINT: begin`ifdef HARDWARE_PRINTcase (phase)0: begin delayedValue[15:8]<=data; address<=address+1; phase<=phase+1; end1: begin delayedValue[7:0] <=data; address<=address+1; phase<=phase+1; end2,3,4: begin DoPrint(delayedValue[14:10]); delayedValue[14:5]<=delayedValue[9:0]; end5: beginprintEnable<=0;if (delayedValue[15]) beginalphabet<=0;long<=0;case (returnValue[1:0])`PRINTEFFECT_FETCH: beginaddress<=pc;state<=`STATE_FETCH_OP;end`PRINTEFFECT_FETCHAFTER: beginpc<=address;state<=`STATE_FETCH_OP;end`PRINTEFFECT_RET1: beginReturnFunction(1);end`PRINTEFFECT_ABBREVRET: beginaddress<=temp;delayedValue<=operand[0];phase<=operand[1];returnValue[1:0]<=returnValue[3:2];endendcaseend else beginphase<=0;endend// branch to abbrev6: beginaddress<='h18;phase<=phase+1;temp<=address;operand[0]<=delayedValue;returnValue[3:2]=returnValue[1:0];returnValue[1:0]=`PRINTEFFECT_ABBREVRET;end7: begin address<=address+1; operand[2][7:0]=data; phase<=phase+1; end8: begin address<=(operand[2][7:0]<<8)|data+2*store; phase<=phase+1; end9: begin address<=address+1; operand[2][7:0]<=data; phase<=phase+1; enddefault: begin address<=2*((operand[2][7:0]<<8)|data); phase<=0; endendcase`elseif (data[7] || returnValue[1:0]!=`PRINTEFFECT_FETCHAFTER) beginif (returnValue[1:0]==`PRINTEFFECT_FETCHAFTER)pc<=address+2;operand[0]<=`PRINT_CALLBACK;$display("Print from %h\n", temp);operand[1]<=temp[0]|((returnValue[1:0]==`PRINTEFFECT_RET1)?2:0); operand[2]<=temp[16:1];operTypes[1]=`OPER_LARGE; operTypes[2]=`OPER_LARGE;CallFunction(returnValue[1:0]==`PRINTEFFECT_RET1, 1);end else beginaddress<=address+2;end`endifend`ifdef HARDWARE_PRINT`STATE_PRINT_CHAR: beginaddress<=pc;printEnable<=0;state<=`STATE_FETCH_OP;end`endifdefault: begin$display("HALT");operand[1]<=(pc>>1);operand[2]<=operand[0];operand[3]<=operand[1];operand[0]<=`EXCEPTION_CALLBACK;//operTypes[0]<=`OPER_LARGE;operTypes[1]<=`OPER_LARGE;operTypes[2]<=`OPER_LARGE;operTypes[3]<=`OPER_LARGE;CallFunction(0,1);endendcaseendendmodulemodule main();reg clk;reg adcDout;reg reset;wire [7:0] data;wire [16:0] address;wire writeEnable;wire printEnable;wire romCS;wire ramCS;wire led0;wire led1;wire led2;wire lcdCS;wire lcdRS;wire lcdReset;wire adcCS;wire a17;wire a18;integer file,readData,i,j,numOps,cycles,stateCycles[15:0],opCycles[255:0],ops[255:0];integer touch,touchX, touchY, touchZ;reg [7:0] mem [128*1024:0];reg [7:0] dynamicMem [128*1024:0];assign data=(!romCS ? mem[address] : (!ramCS ? (!writeEnable ? 8'bZ : dynamicMem[address] ) : 8'bZ ) );initialbegin$display("Welcome");file=$fopen("rom.z3","rb");readData=$fread(mem, file);$display("File read:%h %d", file, readData);$fclose(file);touch=$fopen("touch.txt","r");adcDout=0;reset=1;numOps=0;cycles=0;mem['h1E57F]=1; // Suppress game select screen as it's slowfor (i=0; i<16; i=i+1)stateCycles[i]=0;for (i=0; i<256; i=i+1) beginopCycles[i]=0;ops[i]=0;end//$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);for (i=0; i</*505*/10000000; i=i+1) beginclk=1;#5 clk=0;if (!ramCS && !writeEnable) begindynamicMem[address]=data;end`ifdef HARDWARE_PRINTif (!printEnable) begin$display("PRINT: %c", data);end`endifif (b.state==`STATE_HALT) begin$display("Halt");i=10000000;endif (b.operNum==`OP_VAR && b.op==`OPVAR_GETTOUCH && b.phase==0 && b.state==`STATE_DO_OP) beginb.phase=3;if ($fscanf(touch, "%d %d %d", touchX, touchY, touchZ)==-1) begini=10000000;end$display("Read: %d %d %d", touchX, touchY, touchZ);case (b.operand[0])'h93: b.operand[1]=touchZ;'h95: b.operand[1]=touchX;'h1A: b.operand[1]=touchY;default: begin $display("Bad touch"); $finish; endendcaseendif (b.operNum==`OP_VAR && b.op==`OPVAR_BLIT1 && b.phase==0 && b.state==`STATE_DO_OP) beginb.operand[1]=1;end//if (b.curPC<'h1e000)beginif (b.state==`STATE_FETCH_OP) beginops[b.op+(32*b.operNum)]=ops[b.op+(32*b.operNum)]+1;numOps=numOps+1;endif (b.state!=`STATE_RESET) begincycles=cycles+1;opCycles[b.op+(32*b.operNum)]=opCycles[b.op+(32*b.operNum)]+1;endstateCycles[b.state]=stateCycles[b.state]+1;end$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);endfor (i=0; i<16; i=i+1)if (stateCycles[i]>0)$display("State:%d %d", i, stateCycles[i]);for (i=0; i<256; i=i+1)if (opCycles[i]>0)$display("OpCyc:%d/%d %d/%d=%d", i/32, i%32, opCycles[i], ops[i], opCycles[i]/ops[i]);file=$fopen("ram.dat", "wb");for (i=0; i<'h20000; i=i+16) begin$fwrite(file, "%05h: ", i);for (j=0; j<16; j=j+2)$fwrite(file, "%02x%02x ", dynamicMem[i+j][7:0], dynamicMem[i+j+1][7:0]);for (j=0; j<16; j=j+1)$fwrite(file, "%c", (dynamicMem[i+j][7:0]>=32)?dynamicMem[i+j][7:0]:46);$fwrite(file, "\n");end$fwrite(file, "\nBitmap:\n");for (i='h1b500; i<'h20000; i=i+30) beginfor (j=0; j<30; j=j+1)$fwrite(file, "%d%d%d%d%d%d%d%d",dynamicMem[i+j][7], dynamicMem[i+j][6],dynamicMem[i+j][5], dynamicMem[i+j][4],dynamicMem[i+j][3], dynamicMem[i+j][2],dynamicMem[i+j][1], dynamicMem[i+j][0]);$fwrite(file, "\n");end$fclose(file);$fclose(touch);$finish;endboss b(clk, adcDout, reset, data, address, writeEnable, printEnable, romCS, ramCS, led0, led1, led2, lcdCS, lcdRS, lcdReset, adcCS, a17, a18);endmodule
