📄 executor.java
字号:
/**
* Executor.java 2007/11/16 version1.0
*/
package com.vmpu.core;
import com.vmpu.util.Mask16;
/**
* 执行部件:包括ALU、寄存器堆、标志寄存器和4KB数据缓存等
*
* @author 周良
*
*/
public class Executor {
/**
* 4*16位寄存器堆
*/
private char[] regs = new char[] { 0, 0, 0, 0 };
/**
* 8位标志寄存器 bit0:z flag bit1:c flag
*/
private byte flagReg = 0;
/**
* 数据缓存:4KB
*/
private byte[] dataCache = new byte[1024];
/**
* 所属的MPU
*/
private MicroProcessingUnit owner = null;
/**
* 初始化
*/
public void init() {
for(int i = 0;i < regs.length;i ++)
regs[i] = 0;
flagReg = 0;
for(int j = 0;j < dataCache.length;j ++)
dataCache[j] = 0;
}
/**
* 构造函数,需要指明属于哪一个MPU
* @param owner
*/
public Executor(MicroProcessingUnit owner) {
this.owner = owner;
this.init();
}
/**
* 执行指令操作
*/
public void execute() {
// 有关寄存器恢复到初始状态
flagReg = 0;
// 修改CPU状态寄存器
owner.setStatusReg(MicroProcessingUnit.MPU_EXE);
// ===================================================
// 准备执行数据
// ===================================================
// 取得控制信号
// isRegWr=true,RegWr=1,else,0
boolean isRegWr = (owner.getController().getCtrlSgnlReg() & Mask16.mask16[8]) == Mask16.mask16[8];
// isALUSrc=true,ALUSrc=1,else,0
boolean isALUSrc = (owner.getController().getCtrlSgnlReg() & Mask16.mask16[4]) == Mask16.mask16[4];
// isMemWr=true,MemWr=1,else,0
boolean isMemWr = (owner.getController().getCtrlSgnlReg() & Mask16.mask16[3]) == Mask16.mask16[3];
// isWSrc=true,WSrc=1,else,0
boolean isWSrc = (owner.getController().getCtrlSgnlReg() & Mask16.mask16[2]) == Mask16.mask16[2];
// 取得ALU功能编码
int ALUCtr2 = owner.getController().getCtrlSgnlReg() & Mask16.mask16[7];
int ALUCtr1 = owner.getController().getCtrlSgnlReg() & Mask16.mask16[6];
int ALUCtr0 = owner.getController().getCtrlSgnlReg() & Mask16.mask16[5];
int ALUCtr = (ALUCtr2 >> 5) | (ALUCtr1 >> 5) | (ALUCtr0 >> 5);
// 取得SR、DR地址
int dr_addr = (owner.getController().getImmReg1() & 0x3000) >>> 12;
int sr_addr = (owner.getController().getImmReg1() & 0xC000) >>> 14;
// 取得imm10
int imm10 = (owner.getController().getImmReg1() & 0x0FFC) >>> 2;
// ===================================================
// ALU计算
// ===================================================
// ALU操作数1:总是目的寄存器
int alu_operand1 = regs[dr_addr];
// ALU操作数2:当ALUSrc=0时,是源寄存器;当ALUSrc=1时,是imm10;
int alu_operand2 = isALUSrc ? imm10 : regs[sr_addr];
// ALU操作结果
int alu_out = 0;
// ALU计算
switch (ALUCtr) {
case 0:// 000
case 1:// 001
// 加
alu_out = alu_operand1 + alu_operand2;
// 修改标志寄存器
flagReg = (byte) (((alu_out & 0x10000) == 0x10000) ? (flagReg | 0x02)
: (flagReg & 0xFD));
flagReg = (byte) ((alu_out == 0) ? (flagReg | 0x01)
: (flagReg & 0xFE));
break;
case 2:// 010
case 3:// 011
// 减
alu_out = alu_operand1 - alu_operand2;
// 修改标志寄存器
flagReg = (byte) ((alu_out < 0) ? (flagReg | 0x02)
: (flagReg & 0xFD));// c flag
flagReg = (byte) ((alu_out == 0) ? (flagReg | 0x01)
: (flagReg & 0xFE));// z flag
break;
case 4:// 100
// 与
alu_out = alu_operand1 & alu_operand2;
// 修改标志寄存器
flagReg = (byte) ((alu_out == 0) ? (flagReg | 0x01)
: (flagReg & 0xFE));// z flag
break;
case 5:// 101
// 或
alu_out = alu_operand1 | alu_operand2;
// 修改标志寄存器
flagReg = (byte) ((alu_out == 0) ? (flagReg | 0x01)
: (flagReg & 0xFE));// z flag
break;
case 6:// 110
// 非
alu_out = ~alu_operand1;
// 修改标志寄存器
flagReg = (byte) ((alu_out == 0) ? (flagReg | 0x01)
: (flagReg & 0xFE));// z flag
break;
case 7:// 111
// 传送操作数2
alu_out = alu_operand2;
break;
}
// ===================================================
// 写数据缓存
// ===================================================
if (isMemWr) {
dataCache[alu_out] = (byte) (alu_operand1 >>> 8);
dataCache[alu_out + 1] = (byte) alu_operand1;
}
// ===================================================
// 写寄存器
// ===================================================
if (isRegWr) {
if (isWSrc) {
// data cache->regs
regs[dr_addr] = (char) ((dataCache[alu_out] << 8) | dataCache[alu_out + 1]);
} else {
// alu_out->regs
regs[dr_addr] = (char) alu_out;
}
}
}
public char[] getRegs() {
return regs;
}
public byte getFlagReg() {
return flagReg;
}
public byte[] getDataCache() {
return dataCache;
}
/**
* 装载一个字节的数据到数据缓存
* @param data
*/
public void loadData(byte data,int to) {
if(to >= 0 && to < this.dataCache.length)
this.dataCache[to] = data;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -