サブルーチンコールその1
概要 †
- サブルーチンコールその1のサブルーチン, SubI2C1を使い、I2Cの制御用データを、機能ごとに分割して呼び出しています。
verilog †
- MiniCPUとI2Cバスの接続」の ram.v を以下の ram.v で置き換えて動かします。
- ram.v
// Subroutine calling by the mini CPU.
mem[8'h00] = 16'h1068; // PUSHI i2cStart // push arg1... the i2c slave Addr
mem[8'h01] = 16'h1003; // PUSHI Rtn0 // push the return address
mem[8'h02] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h03] = 16'h1070; // Rtn0: PUSHI i2cAddr // push arg1... the i2c slave Addr
mem[8'h04] = 16'h1006; // PUSHI Rtn1 // push the return address
mem[8'h05] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h06] = 16'h1090; // Rtn1: PUSHI i2cAddrW // push arg1 ... write bit of i2cAddr
mem[8'h07] = 16'h1009; // PUSHI Rtn2 //
mem[8'h08] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h09] = 16'h1098; // Rtn2: PUSHI i2cRAck // push arg1 .... read the ack
mem[8'h0A] = 16'h100C; // PUSHI Rtn3 //
mem[8'h0B] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h0C] = 16'h10B0; // Rtn3: PUSHI i2cD1 // push arg1 ... send register number to the i2c slave
mem[8'h0D] = 16'h100F; // PUSHI Rtn4 //
mem[8'h0E] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h0F] = 16'h1098; // Rtn4: PUSHI i2cRAck // push arg1 .... read the ack
mem[8'h10] = 16'h1012; // PUSHI Rtn5 // push the return address
mem[8'h11] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h12] = 16'h1068; // Rtn5: PUSHI i2cStart // push arg1... the i2c slave Addr
mem[8'h13] = 16'h1015; // PUSHI Rtn6 // push the return address
mem[8'h14] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h15] = 16'h1070; // Rtn6: PUSHI i2cAddr // push arg1 .... the i2c slave addr
mem[8'h16] = 16'h1018; // PUSHI Rtn7 // push the return address
mem[8'h17] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h18] = 16'h1094; // Rtn7: PUSHI i2cAddrR // push arg1 .... read bit of i2cAddr
mem[8'h19] = 16'h101B; // PUSHI Rtn8 // push the return address
mem[8'h1A] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h1B] = 16'h1098; // Rtn4: PUSHI i2cRAck // push arg1 .... read the ack
mem[8'h1C] = 16'h101E; // PUSHI Rtn5 // push the return address
mem[8'h1D] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h1E] = 16'h10d0; // Rtn8: PUSHI i2cRead // push arg1 .... read the data from the slave
mem[8'h1F] = 16'h1021; // PUSHI Rtn9 // push the return address
mem[8'h20] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h21] = 16'hD000; // Rtn9: IN // input msb
mem[8'h22] = 16'h1001; // PUSHI 1
mem[8'h23] = 16'hF003; // SHL
mem[8'h24] = 16'h303A; // POP tmp1
//
mem[8'h25] = 16'h109c; // PUSHI i2cWAck // push arg1 .... write the ack
mem[8'h26] = 16'h1028; // PUSHI Rtn10 // push the return address
mem[8'h27] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h28] = 16'h10D0; // Rtn10: PUSHI i2cRead // push arg1 .... read the data from the slave
mem[8'h29] = 16'h102B; // PUSHI Rtn11 // push the return address
mem[8'h2A] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h2B] = 16'hD000; // Rtn11: in // input lsb
mem[8'h2C] = 16'h100F; // PUSHI 15
mem[8'h2D] = 16'hF004; // SHR
mem[8'h2E] = 16'h303B; // POP temp2
//
mem[8'h2F] = 16'h10A0; // Rtn12 PUSHI i2cNAck // push arg1 .... write the ack
mem[8'h30] = 16'h1032; // PUSHI Rtn13 // push the return address
mem[8'h31] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h32] = 16'h10F0; // Rtn13: PUSHI i2cStop // push arg1 .... write the ack
mem[8'h33] = 16'h1035; // PUSHI Rtn14 // push the return address
mem[8'h34] = 16'h4041; // JMP SubI2C1 // call the subroutine
//
mem[8'h35] = 16'h203A; // Rtn14: PUSH temp1
mem[8'h36] = 16'h203B; // PUSH temp2
mem[8'h37] = 16'hF006; // BOR
mem[8'h38] = 16'hE000; // OUT
mem[8'h39] = 16'h0000; // HALT //
mem[8'h3A] = 16'h0000; // temp1:
mem[8'h3B] = 16'h0000; // temp2:
//
mem[8'h40] = 16'h0000; //
mem[8'h41] = 16'h205C; // SubI2C1: PUSH LblJMP // subroutine. the 1st step to make return instruction
mem[8'h42] = 16'hF006; // BOR // make the return instruction using arg1 and the jump instruction
mem[8'h43] = 16'h305B; // POP RtnSub1 // save the return instruction
mem[8'h44] = 16'h305D; // POP Sub1Data2 // save the arg1
mem[8'h45] = 16'h205D; // PUSH Sub1Data2
mem[8'h46] = 16'h7000; // LD
mem[8'h47] = 16'h3060; // POP N
mem[8'h48] = 16'h205D; // PUSH Sub1Data2
mem[8'h49] = 16'h1001; // PUSHI 1
mem[8'h4A] = 16'hF000; // ADD
mem[8'h4B] = 16'h305E; // POP Sub1SA
mem[8'h4C] = 16'h1000; // PUSHI 0
mem[8'h4D] = 16'h305F; // POP i
mem[8'h4E] = 16'h205F; // L1 PUSH i
mem[8'h4F] = 16'h205E; // PUSH Sub1SA
mem[8'h50] = 16'hF000; // ADD
mem[8'h51] = 16'h7000; // LD ... Sub1S[i];
mem[8'h52] = 16'hE000; // OUT ... print(Sub1S[i]) ;
mem[8'h53] = 16'h205F; // PUSH i;
mem[8'h54] = 16'h1001; // PUSHI 1
mem[8'h55] = 16'hF000; // ADD
mem[8'h56] = 16'h305F; // POP i
mem[8'h57] = 16'h205F; // PUSH i
mem[8'h58] = 16'h2060; // PUSH N
mem[8'h59] = 16'hF001; // SUB
mem[8'h5A] = 16'h604E; // JNZ L1: if(i<n) goto L1;
mem[8'h5B] = 16'h0000; // RtnSub1: JMP // return
mem[8'h5C] = 16'h4000; // LblJMP: 0x4000
mem[8'h5D] = 16'h0000; // Sub1Data2:
mem[8'h5E] = 16'h0000; // Sub1SA:
mem[8'h5F] = 16'h0000; // i:
mem[8'h60] = 16'h0000; // N:
//
// data for controlling i2c
// (MSB) ...... scl, sda (LSB)
//
// I2C start
mem[8'h68] = 16'h0004; // i2cStart: 3
mem[8'h69] = 16'h0001; // 01
mem[8'h6A] = 16'h0003; // 11
mem[8'h6B] = 16'h0002; // 10
mem[8'h6C] = 16'h0000; // 00
//
// I2C addr
mem[8'h70] = 16'h0013; // i2cAddr: x14
mem[8'h71] = 16'h0001; // 01
mem[8'h72] = 16'h0003; // 11 sda 1
mem[8'h73] = 16'h0001; // 01
mem[8'h74] = 16'h0000; // 00
mem[8'h75] = 16'h0002; // 10 sda 10
mem[8'h76] = 16'h0000; // 00
mem[8'h77] = 16'h0002; // 10 sda 100
mem[8'h78] = 16'h0000; // 00
mem[8'h79] = 16'h0001; // 01
mem[8'h7A] = 16'h0003; // 11 sda 1001
mem[8'h7B] = 16'h0001; // 01
mem[8'h7C] = 16'h0000; // 00
mem[8'h7D] = 16'h0002; // 10 sda 10010
mem[8'h7E] = 16'h0000; // 00
mem[8'h7F] = 16'h0001; // 01
mem[8'h80] = 16'h0003; // 11 sda 100101
mem[8'h81] = 16'h0001; // 01
mem[8'h82] = 16'h0003; // 11 sda 1001011 .. 0x4B
mem[8'h83] = 16'h0001; // 01
//mem[8'h84] = 16'h0000; // 00
//
// I2C AddrWrite
mem[8'h90] = 16'h0003; // i2cAddrW: x03
mem[8'h91] = 16'h0000; // 00
mem[8'h92] = 16'h0002; // 10 send 0 ... write
mem[8'h93] = 16'h0000; // 00
//
// I2C AddrRead
mem[8'h94] = 16'h0003; // i2cAddrR: x03
mem[8'h95] = 16'h0001; // 01
mem[8'h96] = 16'h0003; // 11 ... read
mem[8'h97] = 16'h0001; // 01
//
// I2C
mem[8'h98] = 16'h0003; // i2cRAck: x03
mem[8'h99] = 16'h0001; // 01
mem[8'h9A] = 16'h0003; // 11 read ack
mem[8'h9B] = 16'h0001; // 01
//
// I2C Write Ack
mem[8'h9C] = 16'h0003; // i2cWAck: x03
mem[8'h9D] = 16'h0000; // 00
mem[8'h9E] = 16'h0002; // 10 send 0 ... write
mem[8'h9F] = 16'h0000; // 00
//
// I2C NAck
mem[8'hA0] = 16'h0003; // i2cNAck x03
mem[8'hA1] = 16'h0001; // 01
mem[8'hA2] = 16'h0003; // 11 ... read
mem[8'hA3] = 16'h0001; // 01
//
// i2cD1
mem[8'hB0] = 16'h0011; // i2cD1: x11
mem[8'hB1] = 16'h0000; // 00
mem[8'hB2] = 16'h0002; // 10 write 0
mem[8'hB3] = 16'h0000; // 00
mem[8'hB4] = 16'h0002; // 10 write 00
mem[8'hB5] = 16'h0000; // 00
mem[8'hB6] = 16'h0002; // 10 write 000
mem[8'hB7] = 16'h0000; // 00
mem[8'hB8] = 16'h0002; // 10 write 0000
mem[8'hB9] = 16'h0000; // 00
mem[8'hBA] = 16'h0002; // 10 write 00000
mem[8'hBB] = 16'h0000; // 00
mem[8'hBC] = 16'h0002; // 10 write 000000
mem[8'hbd] = 16'h0000; // 00
mem[8'hbe] = 16'h0002; // 10 write 0000000
mem[8'hbf] = 16'h0000; // 00
mem[8'hc0] = 16'h0002; // 10 write 00000000 .... write register 0
mem[8'hc1] = 16'h0000; // 00
//
//
mem[8'hd0] = 16'h0011; // i2cRead x11
mem[8'hd1] = 16'h0001; // 01
mem[8'hd2] = 16'h0003; // 11 read 1st bit
mem[8'hd3] = 16'h0001; // 01
mem[8'hd4] = 16'h0003; // 11 read 2nd bit
mem[8'hd5] = 16'h0001; // 01
mem[8'hd6] = 16'h0003; // 11 read 3rd bit
mem[8'hd7] = 16'h0001; // 01
mem[8'hd8] = 16'h0003; // 11 read 4th bit
mem[8'hd9] = 16'h0001; // 01
mem[8'hda] = 16'h0003; // 11 read 5th bit
mem[8'hdb] = 16'h0001; // 01
mem[8'hdc] = 16'h0003; // 11 read 6th bit
mem[8'hdd] = 16'h0001; // 01
mem[8'hde] = 16'h0003; // 11 read 7th bit
mem[8'hef] = 16'h0001; // 01
mem[8'he0] = 16'h0003; // 11 read 8th bit
mem[8'he1] = 16'h0001; // 01
//
// stop
mem[8'hf0] = 16'h0003; // i2cStop x03
mem[8'hf1] = 16'h0002; // 10
mem[8'hf2] = 16'h0003; // 11 stop the transfering
mem[8'hf3] = 16'h0001; // 01
|