当前位置: 首页 > 后端技术 > Java

CSI404ALU设计

时间:2023-04-01 23:11:39 Java

ICSI404–作业2:ALU设计第二个编程作业建立在第一个完成ALU设计的基础上。现在我们已经创建了一个具有按位逻辑运算和位移功能的长字模拟器,我们可以将它扩展到简单的基于逻辑的算术处理,即加法和减法。我们需要记住,基于逻辑的加法(减法只是对减去的整数的2的补码的加法)仅适用于位向量模式——无需关心操作数是无符号还是有符号。唯一的区别在于位向量的解释和无符号或有符号情况的溢出逻辑的实现。ALU设计的另一个方面是我们需要决定ALU将在操作数(在我们的例子中是长字)。我们还需要一些编码的控制位作为触发ALU操作的选择器。正如我们在di关于汇编和机器指令的讨论,这些控制位来自机器指令的操作码字段或辅助功能部分,以防多个操作被分组以共享一个操作码。为了保持简单,所有使用ALU的指令在我们的设计中都将具有不同的操作码。对于我们的32位机器,ALU类实现必须遵循以下规范:ALU类必须是一个新类,不继承自(即,扩展)任何其他类。ALU对象必须在执行操作之前实例化。换句话说,您不应该计划将ALU开发为静态类。这种选择背后有两个原因。首先,大多数现代通用CPU都有多个ALU来利用指令级并行性。因此,您可能希望稍后扩展您的代码以模拟具有多个ALU实例的功能更强大的CPU。第二个也是更有说服力的原因是以下布尔标志必须是为ALU实例维护。根据以下规范,这些标志的值将在每次操作后自动更新:当ALU运算产生长字值0(即所有位被清除)。算术运算(加/减)还是逻辑运算(包括位移)都无关紧要。当ALU运算产生的长字在2的补码符号解释下被视为负数(即MSB为负数)时,应将负数标志(NF)设置为1(true)。无论是算术运算(加/减)还是逻辑运算(包括位移)都无关紧要。当ALU操作导致从MSB位置进位时,进位标志(CF)应设置为1(true)。这个标志是为了指示无符号加法导致的溢出,但是这个标志必须为每个加/减操作计算,因为机器操作码只工作ks在位向量上而不考虑它们的解释。当ALU运算导致基于2的补码算法的溢出条件时,溢出标志(OF)应设置为1(true)。回想一下,对于纹波进位加法,这是由MSB位置的进位和进位不匹配(XOR)指示的。虽然我们不希望任何逻辑操作设置该位,但只有一个例外。左移运算,移位量为1位,通常代替与2的乘法。这对于移位加乘法特别有用。当这样的乘以2运算结果符号翻转时,显然是溢出,必须设置溢出标志。虽然对于多位左移(k位移位乘以2k)也可能出现相同的情况,但溢出标志不会设置在那里,因为无法确定到底有多少位移位导致溢出。确切的方式如何存储se四面旗帜留给你。在最简单的实现中,您可能希望保留四个布尔变量。然而,真正的CPU硬件专用整个寄存器(与机器字一样长)来存储所有必要的标志,包括刚才描述的四个。该寄存器有不同的名称,例如标志寄存器、状态寄存器或程序状态字(PSW)。PSW的某些位可能未使用。因此,另一种选择是在ALU对象的数据字段中为PSW保留一个长字,并且仅使用最低有效的四位(0-3)。第二种方法更接近地模仿硬件实现。由于很容易忘记哪个位用于哪个标志,使用枚举及其常量实例的序号方法可能会派上用场。如课堂上所讨论的,纹波进位加法器逻辑必须用于long-的加法和减法。字。换句话说,您可能无法通过提取oper的值来使用Java的内置加法/减法使用getSigned或getUnsignedmethods从代表性位向量中获取和,然后使用set方法将结果注入回。逐位加法逻辑使用布尔异或(因为我们暂时使用布尔类型)。你可以用任何你喜欢的方式实现它。虽然您可以组合“&&”和“||”运算符来创建逻辑异或,但还有更简单的替代方案,例如使用按位“^”运算符或使用“!=”简单地比较两个布尔值。在任何情况下,您都需要一个布尔参数(除了两个长字)作为LSB的进位(加法为“0”,减法为“1”,假设位被翻转用于被减去的操作数).ripple-carryadder方法应该看起来有点像:privateLongWordrippleCarryAdd(LongWorda,LongWordb,booleancin)注意这个方法应该负责设置CF和OF标志位。此外,应将其私有化以供A内部使用LU当控制位触发加/减操作时。ALU的公共接口应该只涉及控制代码和必要的操作数作为输入和结果以及标志位作为输出。您必须通过实现以下方法为您的类创建公共接口:a)在创建时,必须清除标志位或状态寄存器(取决于您的实现选择)(初始化为“0”)。b)根据您对条件标志的实现来实现访问器。您可以为每个标志(例如,getZF、getNF、getCF和getOF)使用一个访问器,或者为整个程序状态字(getStatus)使用一个访问器。当您的CPU需要检查标志的布尔值(在下一次赋值中)时,它需要在第二种情况中提取正确的位。这同样适用于您当前的测试程序。c)实现唯一的根据给定的控制代码执行ALU操作的修改器。这原型可能看起来像publicLongWordoperate(intcode,LongWordop1,LongWordop2)注意这个变元方法不仅返回ALU运算的结果作为一个长字,而且对条件标志有适当的副作用。控制代码必须完全如下表-否则机器操作码将不匹配:OperationMachineopcodeALUcodeOP1OP2ZFNFCFOFAND1000000(0)Operand1Operand2ifzeroif-iveXXOR1001001(1)Operand1Operand2ifzeroif-iveXXXORNOT10101010010(2)010(2)Operand1OperandOperand211…1(-1)ifzeroifzeroif-iveif-iveXXXXADD1011011(3)Operand1Operand2如果为零if-iveCout(31)OverflowSUB1100100(4)Operand1Operand2如果为零如果-iveCout(31)OverflowSLL1101101(5)如果-iveXamontt=1andsign-flipSRL1110110(6)如果为零则操作数数量XXXSRA1111111(7)如果-iveXXIn如果为零则操作数数量所有方法,您必须在适当的地方验证输入。您must提供一个实现voidrunTests方法的测试文件(TestALU.java),并从您的main中调用它,以及您现有的测试。与其他测试一样,这些测试必须彼此独立,并且必须有合理的覆盖范围。您无法合理地测试所有数十亿种可能的组合,但您可以测试一些有代表性的样本。如果您更新了LongWord.java文件中的源代码,请确保包含兼容的更新版本。您必须提交可构建的.java信用档案.WX:codehelp