⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 executor.java

📁 一个微处理器的模似器
💻 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 + -