免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

头歌运算器设计实验:进位链、标志位与ALU集成

头歌运算器设计实验:进位链、标志位与ALU集成 简介华中科技大学计算机组成原理课程配套的运算器设计实验报告由谭志虎教授指导对应头歌实验平台面向正在学习数字逻辑与计算机组成原理、需要完成 Logisim 运算器实验的本科生。压缩包内仅含 1 个 doc 文档约 779KB结构完整涵盖封面信息、实验目的、原理推导、电路图说明、验证记录与心得体会便于对照课程要求整理报告。正文围绕 8 位可控加减法器、CAL182 电路、4 位与 16 位快速加法器以及 32 位 MIPS 运算器展开既梳理串行进位、并行进位链、溢出检测、成组进位生成与传递函数等关键原理也给出多组输入输出实例和结果分析完整呈现从理论推导到仿真验证的过程可帮助读者理解补码加减、CLA74182 与 CLA74128 的用法及设计思路。目前已有 1548 人学习适合作为实验预习、报告撰写和电路调试的参考范本。1. 头歌运算器设计实验的卡点进位链和标志位才是分水岭打开头歌实验平台的计算机组成原理课程清单运算器设计这一关通常排在加法器之后。多数人第一反应是全加器而已画两下就过真正动手才发现时间全耗在两件事上16 位快速加法器的进位链怎么也压不下去以及溢出标志在边界用例上死活对不上。华中科技大学谭志虎老师这门课的实验报告在同学之间流传很广可报告能抄电路跑不通还是交不了差。这道题的考点其实就三块补码加减法的统一处理、先行进位的分级结构、ALU 功能选择与标志位生成。前三块决定电路能不能过,第四块决定你能不能自己证明它是对的。适合正在做这个实验的在校生也适合想把加法器和 ALU 这条底层线路重新捋一遍的从业者。2. 补码加减法电路可控加减法器怎么一次搭对2.1 减法交给加法器按位取反加一的三步走运算器不单独造减法器这是所有教科书的标准做法。A − B 在补码里等价于 A (−B)而 −B 的补码等于 B 按位取反再加一。落到电路上就是三步B 的每一位与减法控制信号 sub 异或得到条件取反的结果最低位进位输入端接 sub天然完成加一高位进位链和加法时完全共用。这样做的收益很直接一条进位链同时服务加减两种运算硬件复用率翻倍。代价是控制信号要一路扇出到 8 个异或门位宽越大走线越长。常见做法是在 Logisim 里用一个分线器把 sub 拆成 8 路或者干脆复制一个 sub 隧道标签贴在每个异或门旁边后者连线更清爽。需要注意一点异或门的两个输入端不能接反顺序上的直觉——sub 为 1 时取反为 0 时保持原值写成b ^ sub别写成sub ^ 1之类的顺手错误。2.2 CF 与 OF 必须分开判进位不等于溢出这是实验报告里最容易被扣分的地方。8 位无符号数 0xFF 0x01 0x00进位 CF 为 1但它不是有符号溢出8 位有符号数 0x7F 0x01 0x80结果从 127 变成 −128这才是溢出而 CF 此时为 0。两个标志位服务两套解释体系判据自然不同。场景数值示例CFOF含义无符号进位0xFF 0x0110无符号运算超出 255有符号溢出0x7F 0x0101正溢出结果符号翻转有符号负溢出0x80 0x8011两个负数相加得正正常加法0x10 0x2000无异常判据本身很短OF 等于最高位进位与次高位进位的异或也就是Cn ⊕ Cn-1CF 在加法时取 Cn在减法时取 Cn 的取反借位语义。提示不要在减法时对 CF 再做一次异或运算凑公式直接把最高位进位和 sub 异或一次即可cf carry_out ^ sub逻辑最省。2.3 8 位可控加减法器的引脚定义与实现动手之前先把引脚表写进报告后面查错全靠它。下面是一份可以直接抄进实验报告的接口定义。信号位宽方向说明a8输入被加数 / 被减数b8输入加数 / 减数sub1输入0 为加法1 为减法f8输出运算结果cf1输出加法进位 / 减法借位of1输出有符号溢出电路搭完后用一段 Verilog 行为描述做对照比在纸上推一遍快得多module add_sub8( input [7:0] a, input [7:0] b, input sub, // 0: 加法 1: 减法 output [7:0] f, output cf, // sub0 为进位, sub1 为借位 output of ); wire [7:0] b_xor b ^ {8{sub}}; // 减法时按位取反 wire [8:0] sum {1b0, a} {1b0, b_xor} sub; // 最低位加 sub 完成 1 assign f sum[7:0]; assign cf sum[8] ^ sub; // 减法时进位取反即借位 assign of sum[8] ^ sum[7]; // 最高两位进位异或 endmodule这段代码里sum特意声明成 9 位就是为了把最高位进位保留下来。b_xor用位拼接复制 sub等价于 8 个异或门并排cf的那一次异或承担了加法进位与减法借位的语义切换of只看第 7 位和第 8 位跟结果的其他位无关。验证时优先跑 0x7F0x01、0x800x7F、0xFF0x01 三组基本能覆盖全部边界。3. 先行进位加法器从 4 位 CLA 到 16 位组间并行3.1 Gi 与 Pi把进位从逐级传递改成提前算出行波进位加法器慢在哪儿每一位都要等低位的进位算完才能动16 位意味着 16 次串行等待。先行进位的思路是换一组中间量本位能否自己产生进位叫生成信号 G本位能否把低位进位原样传上去叫传递信号 P。定义只有两行Gi Ai · Bi Pi Ai ⊕ Bi有了 G 和 P进位就能直接展开成不含递归的形式Ci1 Gi Pi·Ci。继续往下代C2、C3、C4 全是与门和或门的组合只跟 C0 和各位的 G、P 有关谁也不用等谁。4 位一组的展开式长这样C1 G0 P0·C0 C2 G1 P1·G0 P1·P0·C0 C3 G2 P2·G1 P2·P1·G0 P2·P1·P0·C0 C4 G3 P3·G2 P3·P2·G1 P3·P2·P1·G0 P3·P2·P1·P0·C0盯着 C4 那一行看去掉末项后剩下的部分就是这一组的成组进位生成信号 G*而 P3P2P1P0 就是成组进位传递信号 P*。这两个量是搭 16 位加法器的钥匙。3.2 组内并行、组间串行、组间并行三种接法的延迟账16 位加法器通常拆成 4 个 4 位 CLA 组组间怎么接决定了最终速度。三种接法的差别在报告里必须有对比否则只算完成了能跑没完成设计。结构组间连接方式门级延迟特点行波进位进位逐位串约 32 级结构最简单位宽一大就崩组间串行前一组 C4 接后一组 C0约 4 × 组内延迟实现容易速度提升有限组间并行各组输出 G*、P* 交给 CLG 统一算约 7 级延迟最低多用一片进位生成器组间串行是很多人第一次交上去的版本4 片 4 位 CLA 首尾相接看着比行波进位高级实际延迟只降了四分之三因为组与组之间还在排队。组间并行的做法是每组额外输出 G*、P*送到一片独立的先行进位生成器 CLG由它一次性算出 C4、C8、C12、C16再回送给各组内部当 C0 用。代价是多一片逻辑收益是进位延迟从组数 × 组内延迟压到常数级。注意组间并行时每组内部的进位方程里 C0 换成 CLG 送来的那一路别让组内 CLA 第一级的进位再走隧道标签两个来源打架是最隐蔽的错。3.3 用 Logisim 封装可复用的 4 位 CLA 子电路在 Logisim 里搭这套结构先解决重复劳动问题。第一步用隧道标签统一命名进位和中间量进位叫c0、c4、c8生成传递叫g0、p0。同名标签自动连通省掉大量拉线排查时也好找。第二步用分线器把 4 位输入拆成 4 条单位线G 和 P 的信号源就在这里取。进位方程的长串与或项手写容易漏项可以用几行 Python 把式子打印出来照着连线或者贴进报告def cla_carry(n4): out [] for i in range(1, n 1): expr [fG{i-1}] # 本组自己产生进位 prod [] for j in range(i - 1, 0, -1): prod.append(fP{j}) expr.append(*.join(prod) f*G{j-1}) # 中间某位产生并被高位传递 prod.append(P0) expr.append(*.join(prod) *C0) # 一路传到本组的低位进位 out.append(fC{i} .join(expr)) return out print(\n.join(cla_carry(4)))i控制要算第几级进位内层循环负责拼接 P 链的长度从本级一直往下缩到 P0。跑出来的四行正好对应上一节的表达式可以逐项核对有没有漏掉P2·P1·G0这类中间项。搭完 4 位 CLA 后选中整个电路用 Add Circuit 封装成子电路把 a、b、c0 设成输入引脚f、c4、g、p 设成输出引脚外观按引脚位置排整齐。之后实例化四份拼 16 位组间串行和组间并行只差最后一次连线切换成本极低。4. ALU 功能集成op 译码、标志位与测试向量4.1 op 编码怎么定8 种功能的统一出口运算器设计实验最后一步是把加法器、逻辑运算、移位之类的功能塞进同一个模块由操作码选路。功能表要在动手前定死不然后面加功能容易把译码逻辑接乱。下面这份 8 功能表是常见做法op 取 3 位。op[2:0]功能表达式是否用进位链000加A B是001减A ~B 1是010与A B否011或A | B否100异或A ^ B否101取反~A否110传送A否111自增A 1是实现上先把 op 送进 3-8 译码器得到 8 条独热信号每条去控制一个多路选择器的输入端。加法器永远在算只是结果被不被选中由 op 决定。这样的好处是结构规整加功能只需要多接一路 Mux 输入缺点是加法器一直在翻转功耗不优——但在课程实验的量级上完全不用管。4.2 ZF、SF、CF、OF 的生成电路四个标志位里ZF 最容易写错。它的定义是结果全零等价于 8 个结果位全部取或非先或归约再取反两级门就够别用 8 输入与门硬接那样扇入过大、图也难看。SF 直接取结果的最高位一位线连出去即可。CF 和 OF 沿用第 2 章的判据但要补一条约定逻辑运算时 OF 与 CF 怎么处理报告里必须写明。常见约定是逻辑运算时 CF、OF 清零因为进位和溢出对按位运算没有意义。这个约定不写清楚评测用例只要涉及A AND B之后读标志位就会莫名其妙地失败。4.3 用 Python 参考模型批量生成测试向量手工敲十组用例谁都会关键是覆盖边界。用一段参考模型批量生成向量再挑重点往电路里喂效率高很多。import csv, random def alu_ref(a, b, op): a 0xFF; b 0xFF if op 0: # 加 s a b f s 0xFF cf (s 8) 1 of ((a ^ f) (b ^ f) 0x80) ! 0 elif op 1: # 减 s a (b ^ 0xFF) 1 f s 0xFF cf 1 - ((s 8) 1) # 借位为 1 of ((a ^ b) (a ^ f) 0x80) ! 0 elif op 2: f, cf, of a b, 0, 0 elif op 3: f, cf, of a | b, 0, 0 elif op 4: f, cf, of a ^ b, 0, 0 elif op 5: f, cf, of (~a) 0xFF, 0, 0 elif op 6: f, cf, of a, 0, 0 else: s a 1 f, cf s 0xFF, (s 8) 1 of (a 0x7F) zf 1 if f 0 else 0 sf (f 7) 1 return f, cf, of, zf, sf cases [(0x7F,0x01,0),(0x80,0x80,0),(0xFF,0x01,0), (0x00,0x01,1),(0x80,0x01,1),(0x7F,0xFF,1)] random.seed(20240501) for _ in range(200): cases.append((random.randrange(256), random.randrange(256), random.randrange(8))) with open(alu_vectors.csv, w, newline) as fp: w csv.writer(fp) w.writerow([a,b,op,f,cf,of,zf,sf]) for a, b, op in cases: f, cf, of, zf, sf alu_ref(a, b, op) w.writerow([f0x{a:02X}, f0x{b:02X}, op, f0x{f:02X}, cf, of, zf, sf])减法分支里cf 1 - ((s 8) 1)是借位的翻转写法别和加法分支搞混。溢出用符号位公式判断(a ^ f) (b ^ f)抓的是两个加数符号相同但结果符号变了这一情况减法分支换成(a ^ b)打头。自增那一路只有 a 参与溢出条件退化成 a 等于 0x7F 这一种。生成的 CSV 手动挑十几条输进电路或者在 Logisim 里用 Project 菜单下的组合逻辑分析功能导真值表做比对重点是那六条手工用例必须在里面。5. 验收排错与实验报告写法把电路和结论对上5.1 三个高频接错点和定位手法排错时按下面的顺序查能省掉大半时间。一是位宽不匹配。Logisim 对位宽不一致的连线会标红或者静默截断CLA 内部的进位是单位线结果总线是 8 位混接一次后面全乱。看到输出高低位明显规律错乱先查分线器和位扩展器。二是隧道标签重名。c4这个标签在组内和组间两处都贴就可能把不该连的节点短接。定位办法是把可疑标签临时改名成c4_tmp看现象是否变化。三是标志位取自错误的级。OF 应该取最高位的两位进位有人图省事取整个加法器的最高进位跑 0x7F0x01 时 CF 和 OF 全错。用第 2 章那三组边界用例逐个打表五分钟能定位。5.2 报告里必须出现的表格与参数一份能拿得出手的运算器设计实验报告除了电路截图至少要有这几张表引脚定义表见 2.3、ALU 功能表见 4.1、标志位约定说明、以及下面这种测试用例表。用例abop期望 f期望 CF期望 OF验证点正溢出0x7F0x01加0x8001OF 单独置位负溢出0x800x80加0x0011CF 与 OF 同时置位ZF 也置位无符号进位0xFF0x01加0x0010CF 单独置位借位0x000x01减0xFF10减法的 CF 语义逻辑清零0xF00x0F与0x0000逻辑运算标志位清零约定延迟对比也要写进去行波进位、组间串行、组间并行三种结构的门级延迟数字摆在同一张表里配上为什么选组间并行的说明这一节往往就是评分区分度所在。0xFF 0x01 和 0x7F 0x01 这两条用例建议留在报告的最后一页它们是唯一能一次分清 CF 和 OF 语义的两组数据。本文还有配套的精品资源点击获取
返回列表