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

📄 controller.java

📁 一个微处理器的模似器
💻 JAVA
字号:
/**
 * Controller.java 2007/11/15 version1.0
 */
package com.vmpu.core;

import com.vmpu.util.Mask16;

/**
 * 控制器在时钟控制下,负责从指令寄存器中取出指令,并根据标志位把其翻译成各种控制信号并产生各种立即数。
 * 
 * 各控制信号的含义如下: RegWr:写寄存器,RegWr=0时,禁止写;RegWr=1时,写使能 ALUCtr:选择ALU功能,参见ALU功能编码
 * ALUSrc:选择ALU的源操作数,ALUSrc=0时,源操作数为SR;ALUSrc=1时,源操作数为立即数
 * MemWr:写内存,MemWr=0时,禁止写;MemWr=1时,写使能
 * WSrc:选择busW的值,WSrc=0时,选择ALU运算结果:WSrc=1时,选择存储器读取
 * nPC_sel1:PC计算方式,nPC_sel1=0时,PC=PC+2;nPC_sel1=1时,PC=PC+OFFSET
 * nPC_sel2:PC计算方式,nPC_sel2=0时,PC= PC+OFFSET;nPC_sel2=1时,PC=ADR
 * Flag_C:C标志,影响JNC指令 Flag_Z:Z标志,影响JNZ指令
 * 
 * 各控制信号的计算方式如下: RegWr=instr<15>+!instr<14>&!instr<12>+instr<14>&instr<13>&instr<12>
 * ALUCtr<2>=!instr<15>+instr<14> ALUCtr<1>=!instr<15>+instr<13> ALUCtr<0>=!instr<15>+instr<12>
 * ALUSrc=instr<15>&!instr<14>&instr<12>+!instr<15>&instr<14> MemWr=!instr<15>&!instr<14>&instr<12>
 * WSrc=!instr<15>&!instr<14> nPC_sel1比较特殊,除了受操作码影响外,还受标志位的影响: nPC_sel1=!instr<15>&instr<14>&!instr<13>&instr<12>!Flag_C
 * +!instr<15>&instr<14>&instr<13>&!instr<12>!Flag_Z nPC_sel2=!instr<15>&!instr<13>&!instr<12>
 * 
 * 这些控制信号总共需要用9位来表示,可以设想有一个16位的控制信号寄存器,控制器完成译码后, 把各种信号寄存在该寄存器里,以供其他部件使用。
 * 
 * 另外,会产生三种不同类型的立即数: imm10:指令低10位; imm12:指令低12位; imm2:常数2(二进制表示为10)。
 * 
 * 这些立即数总共需要用24位表示,可以设想有两个16位的立即数寄存器,用来寄存这些立即数
 * 
 * 还会产生SR、DR的地址 SR、DR共需要用4位来表示
 * 
 * @author 周良
 * 
 */
public class Controller {
	/**
	 * 16位的控制信号寄存器,各控制信号所占的位如下: bit15~bit9:未定义 bit8:RegWr bit7:ALUCtr<2>
	 * bit6:ALUCtr<1> bit5:ALUCtr<0> bit4:ALUSrc bit3:MemWr bit2:WSrc
	 * bit1:nPC_sel1 bit0:nPC_sel2
	 * 
	 * 初始化为0,此时寄存器和内存均禁止写
	 * 
	 * 控制信号寄存器只有控制器能够修改,其他部件只能读取
	 */
	private char ctrlSgnlReg = 0;

	/**
	 * 16位的立即数寄存器1,用来寄存imm10和imm2: bit1~bit0:imm2 bit11~bit2:imm10
	 * bit13~bit12:DR地址 bit15~bit14:SR地址
	 * 
	 * 初始化为2,这是因为imm2是常数2
	 * 
	 * 立即数寄存器1只有控制器能够修改,其他部件只能读取
	 */
	private char immReg1 = 2;

	/**
	 * 16位的立即数寄存器2,用来寄存imm12: bit0~bit11:imm12 bit12~bit15:未定义
	 * 
	 * 初始化为0
	 * 
	 * 立即数寄存器2只有控制器能够修改,其他部件只能读取
	 */
	private char immReg2 = 0;
	
	/**
	 * 所属的MPU
	 */
	private MicroProcessingUnit owner = null;
	
	/**
	 * 初始化
	 */
	public void init() {
		ctrlSgnlReg = 0;
		immReg1 = 2;
		immReg2 = 0;
	}
	
	/**
	 * 构造函数,需要指明属于哪一个MPU
	 * @param owner
	 */
	public Controller(MicroProcessingUnit owner) {
		this.owner = owner;
		this.init();
	}

	/**
	 * 从指令寄存器中取出指令,并根据标志位把其翻译成各种控制信号并产生各种立即数
	 */
	public void decode() {
		// 各寄存器恢复到初始状态
		this.init();
		// 修改MPU状态寄存器
		owner.setStatusReg(MicroProcessingUnit.MPU_DECODE);
		// ===================================================
		// 获取指令和标志
		// ===================================================
		// 从指令寄存器中读取指令
		int instr = owner.getInstrFetcher().getInstrReg();
		// 异常指令,MPU停止执行
		if(instr == 0) owner.halt();
		// 从标志寄存器中读取标志位
		int flag = owner.getExecutor().getFlagReg();

		// ===================================================
		// 产生控制信号
		// ===================================================
		// 分别取得指令的bit15~bit12(操作码部分),并全部移至最低位
		int instr15 = (instr & Mask16.mask16[15]) >>> 15;// instr<15>
		int instr14 = (instr & Mask16.mask16[14]) >>> 14;// instr<14>
		int instr13 = (instr & Mask16.mask16[13]) >>> 13;// instr<13>
		int instr12 = (instr & Mask16.mask16[12]) >>> 12;// instr<12>
		// 指令的bit15,bit14,bit13,bit12取反
		int not_instr15 = (~instr15) & Mask16.mask16[0];
		int not_instr14 = (~instr14) & Mask16.mask16[0];
		int not_instr13 = (~instr13) & Mask16.mask16[0];
		int not_instr12 = (~instr12) & Mask16.mask16[0];
		// 取得C、Z标志
		int flag_c = (flag & Mask16.mask16[1]) >>> 1;// Flag_c
		int flag_z = (flag & Mask16.mask16[0]) >>> 0;// Flag_z
		// !C,!Z
		int not_flag_c = (~flag_c) & Mask16.mask16[0];
		int not_flag_z = (~flag_z) & Mask16.mask16[0];
		// RegWr=instr<15>+!instr<14>&!instr<12>+instr<14>&instr<13>&instr<12>
		int RegWr = instr15 | (not_instr14 & not_instr12)
				| (instr14 & instr13 & instr12);
		// ALUCtr<2>=!instr<15>+instr<14>
		int ALUCtr2 = not_instr15 | instr14;
		// ALUCtr<1>=!instr<15>+instr<13>
		int ALUCtr1 = not_instr15 | instr13;
		// ALUCtr<0>=!instr<15>+instr<12>
		int ALUCtr0 = not_instr15 | instr12;
		// ALUSrc=instr<15>&!instr<14>&instr<12>+!instr<15>&instr<14>
		int ALUSrc = (instr15 & not_instr14 & instr12)
				| (not_instr15 & instr14);
		// MemWr=!instr<15>&!instr<14>&instr<12>
		int MemWr = not_instr15 & not_instr14 & instr12;
		// WSrc=!instr<15>&!instr<14>
		int WSrc = not_instr15 & not_instr14;
		// nPC_sel1=!instr<15>&instr<14>&!instr<13>&instr<12>&!Flag_C
		// +!instr<15>&instr<14>&instr<13>&!instr<12>&!Flag_Z
		int nPC_sel1 = (not_instr15 & instr14 & not_instr13 & instr12 & not_flag_c)
				| (not_instr15 & instr14 & instr13 & not_instr12 & not_flag_z);
		// nPC_sel2=!instr<15>&!instr<13>&!instr<12>
		int nPC_sel2 = not_instr15 & not_instr13 & not_instr12;
		// 把各控制信号寄存到控制信号寄存器的相应位
		ctrlSgnlReg |= RegWr << 8;
		ctrlSgnlReg |= ALUCtr2 << 7;
		ctrlSgnlReg |= ALUCtr1 << 6;
		ctrlSgnlReg |= ALUCtr0 << 5;
		ctrlSgnlReg |= ALUSrc << 4;
		ctrlSgnlReg |= MemWr << 3;
		ctrlSgnlReg |= WSrc << 2;
		ctrlSgnlReg |= nPC_sel1 << 1;
		ctrlSgnlReg |= nPC_sel2 << 0;

		// ===================================================
		// 产生立即数
		// ===================================================
		int imm10 = instr & 0x03FF;
		int imm12 = instr & 0x0FFF;
		immReg1 |= imm10 << 2;
		immReg2 |= imm12;

		// ===================================================
		// 产生SR、DR地址
		// ===================================================
		int dr_addr = instr & 0x0C00;
		int sr_addr = instr & 0x0300;
		immReg1 |= dr_addr << 2;
		immReg1 |= sr_addr << 6;
	}

	public char getCtrlSgnlReg() {
		return ctrlSgnlReg;
	}

	public char getImmReg1() {
		return immReg1;
	}

	public char getImmReg2() {
		return immReg2;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -