【头歌·计组·自己动手画CPU】二、运算器设计(实战拆解版) 【计算机硬件系统设计】
1. 从零搭建运算器的核心逻辑当你第一次打开Logisim准备画CPU运算器时可能会被各种逻辑门和线路搞得头晕。别担心我们先从最基础的一位全加器开始就像搭积木一样逐步构建复杂功能。我当年做这个实验时在理解进位传递上卡了整整两天后来发现只要掌握三个关键信号就能豁然开朗。全加器的本质是处理三个输入A、B和低位进位Cin输出两个结果和S与进位Cout。这里有个实用技巧用异或门计算和SA⊕B⊕Cin用与门或门组合计算进位A·B (A⊕B)·Cin。在Logisim中你可以直接调用内置的全加器组件但亲手用基础门电路搭建一次会深刻理解计算机如何做加法。图示使用与门、或门、异或门搭建的标准一位全加器结构注意进位链的走向2. 可控加减法单元的设计陷阱把多个全加器串联就能实现多位加法但要支持减法运算就需要可控取反机制。这里有个容易踩坑的地方计算机中减法是通过补码转换为加法实现的即A-B A(¬B1)。在电路设计中我们用Sub控制信号同时控制两个关键操作通过异或门阵列实现按位取反当Sub1时B的每位与Sub异或得到¬B将Sub信号作为最低位进位输入相当于1操作// 行为级Verilog描述供参考 module add_sub( input [7:0] A,B, input Sub, output [7:0] Result, output Overflow ); wire [7:0] B_modified B ^ {8{Sub}}; assign {Overflow,Result} A B_modified Sub; endmodule溢出判断是另一个重点。正正得负或负负得正时才发生溢出可以通过最高位进位与次高位进位异或来检测。我在调试时曾用四种测试用例验证正正0x7F0x01正负0x7F0xFF负正0x800x01负负0x800x803. 先行进位电路的性能飞跃当位数增加到32位时行波进位加法器的延迟会变得难以接受。这时候**CLACarry Lookahead Ahead**技术就是救星。它的核心思想是提前计算所有位的进位而不是等待低位慢慢传递。这就像快递分拣中心提前知道所有包裹路线不用等前一个包裹送达才处理下一个。四位CLA182电路的实现需要掌握两个关键信号生成信号GiAi·Bi本位一定产生进位传递信号PiAiBi进位是否继续传递// Logisim中CLA的典型实现 C0 G0 P0·Cin C1 G1 P1·G0 P1·P0·Cin C2 G2 P2·G1 P2·P1·G0 P2·P1·P0·Cin C3 G3 P3·G2 P3·P2·G1 P3·P2·P1·G0 P3·P2·P1·P0·Cin实测表明32位行波进位加法器延迟约160ns而采用4位CLA组间行波进位的设计可将延迟降到40ns。如果使用多级CLA如两层CLA结构还能进一步优化到25ns左右。4. 完整32位ALU的模块化集成现在我们把所有模块组装成真正的运算器。一个典型的MIPS ALU需要支持8种操作加、减、与、或、异或、置位、算术右移、逻辑左移。这里推荐多路选择器树的设计方法第一层选择加减法结果第二层混合逻辑运算结果第三层处理移位操作在Logisim中巧妙使用隧道标签能让电路更清晰。比如我把所有模块的CarryOut统一命名为COUT这样连线时自动建立连接。以下是关键控制信号真值表ALUop[2:0]功能备注000A B带溢出检测的加法001A - B补码减法010A B按位与011AB100A ^ B按位异或101A B逻辑左移低位补0110A B算术右移符号位扩展111SLT符号比较AB时置1最后测试时一定要覆盖边界情况比如0xFFFFFFFF1的溢出、0x80000000算术右移、以及0x55AA55AA与0x00FF00FF的逻辑操作。建议保存测试向量文件方便后续调试。完成这个设计后你会突然理解为什么计算机教材总说运算器是CPU的数学大脑。当我第一次看到自己设计的ALU正确执行32位乘法时那种成就感比通关任何游戏都强烈。记住每个复杂电路都是由简单模块组合而成的关键是要理解每个信号背后的数学意义。