简介运算器实验是计算机组成原理课程中的核心实践环节这份PDF资料围绕74LS181算术逻辑运算器完整介绍了算术运算、逻辑运算和基于“累加-移位”原理的串行乘法实验。内容涉及拨码开关经三态门74LS244输入数据、74LS273寄存器REG_0/REG_1存储中间结果、数码管显示输出等通路结构并通过控制信号ALU_S0至S3、M、CN的不同组合实现A加B、A减B及逻辑运算详细记录不同组合下的运算结果与分类分析帮助学习者理解数据输入、运算、存储和输出的完整流程同时弄清有符号数与无符号数运算的区别以及进位、零、符号标志位的含义。资源为单个PDF文档大小约为2.7兆字节阅读和打印均很方便。目前已有603人学习下载适合用来自主预习、对照实验要求进行实操复盘或撰写实验总结也能为理解中央处理器中运算器的工作机制提供具体参考。1. 运算器实验为什么总绕不开 74LS181很多人在计算机组成原理实验课上第一次被问倒不是不懂加法器而是面对一桌子 74LS181、74LS244、74LS273 不知从哪下手。这类实验的核心只有一件事用两片 74LS181 拼出一个 8 位 ALU再围绕它搭数据通路把算术运算、逻辑运算和“累加-移位”串行乘法全部跑通。适合正在上组成原理实验课、或者拿到实验箱却对着原理图发懵的读者。读完这篇你能独立完成拨码开关置数、控制信号设置、标志位判断以及 8 位乘法的手动执行与结果验证也能理解为什么实验指导书里那些看似绕圈子的步骤其实每一步都在解决总线竞争和中间结果暂存的问题。2. 数据通路角色拆解74LS244、74LS273、74LS194 各干什么2.1 为什么总线上必须有三态门整个实验的数据通路只有一条 BUS输入、运算结果、寄存器回写都挂在同一条线上。如果多个器件同时驱动总线轻则逻辑紊乱重则烧毁 TTL 芯片。三态门 74LS244 在这里就是总线的“门卫”它的输出端有高电平、低电平、高阻三种状态高阻态相当于从物理上断开连接让出总线。实验中ALU 的运算结果经过三态门 74LS244 接到 BUS。控制信号 ALU_EN 控制这个三态门的使能端。启动仿真前令 ALU_EN1此时 ALU 结果不对总线生效需要读数时再令 ALU_EN0原文记作 ALU_EN0三态门才把 F 端结果放到总线上送到绿色数码管显示。这个先屏蔽后导通的顺序是后面所有读写操作的前提。另外输入单元拨码开关也经过一片 74LS244 进总线。两片 74LS244 共用一条 BUS但绝不允许同时导通。实验台通过不同的使能信号错开它们写数据时数据源的三态门开、运算器结果的三态门关读结果时反过来。理解了这一点就不会在拨码开关还没拨完的时候急着去看数码管——那个时刻总线上根本不是稳定数据。2.2 REG_0、REG_1 和 DRA、DRB 的定位差异数据通路的右上方有两片 74LS273构成 8 位寄存器 REG_0 和 REG_1。74LS273 是八路 D 触发器公共时钟端上升沿把 D 端数据锁进 Q 端没有使能端数据来了就锁简单直接。它们在实验中的定位是“中间结果暂存区”串行乘法里被乘数要长时间驻留部分积的高 8 位在加法前后也要有个落脚点这些都由 REG_0 和 REG_1 承担。DRA 和 DRB 则是另一类器件由移位寄存器 74LS194 级联构成的 8 位缓存器。74LS194 是 4 位双向移位寄存器S1S0 控制工作模式实验中 S00、S11 对应右移。DRA 和 DRB 在普通运算中就是普通缓存器但在乘法中它们还要承担移位功能每轮循环结束DRA 和 DRB 联成一体右移一位。REG_0/REG_1 与 DRA/DRB 的分工可以这样记前者做静态暂存后者做动态移位与数据搬运。2.3 写缓存和读结果的标准时序74LS273 是上升沿锁存所以写 DRA 或 DRB 时必须把数据在总线上稳定一段时间后再给时钟。这个先稳定数据、再送时钟的次序比数据本身更重要。下面这段 Verilog 描述的是实验台上写 DRA 的操作序列task write_dra(input [7:0] val); begin alu_en 1b1; // 关闭 ALU 三态门让出总线 #10 bus_data val; // 拨码开关把数据送上 BUS #10 alu_clk 1b0; // 时钟置低准备上升沿 #10 alu_clk 1b1; // 上升沿74LS273 完成锁存 #10 alu_clk 1b0; alu_en 1b0; // 后续操作可恢复总线控制 end endtask代码里的alu_en对应实验台上的 ALU 输出使能alu_clk对应 DRA/DRB 的锁存时钟。#10表示延时 10 个时间单位目的是把“数据建立”和“时钟跳变”隔开。如果不先让出总线写入数据会和 ALU 的输出冲突如果数据没稳定就送时钟锁存进去的可能是毛刺。读运算结果时反过来保证alu_oe三态门输出使能为低让 F 端结果上总线同时留意标志位锁存时钟的下降沿CF、SF、ZF 就是在那个沿被 74LS273 抓住的。下表把数据通路里的器件角色汇总一下写实验报告时可以直接套用器件作用关键特性74LS244三态缓冲器隔离总线低电平使能高阻态让出总线74LS2738 位 D 触发器寄存器上升沿锁存74LS1944 位双向移位寄存器S1S001 时右移74LS1814 位 ALU 核心S、M、CN 共同决定运算功能3. 控制信号组合规律S、M、CN 怎么决定一次运算3.1 两片 74LS181 串行进位8 位 ALU 的基础结构74LS181 本身是 4 位 ALU8 位运算器由两片级联低 4 位 ALU_L4B 的进位输入接外部控制信号 ALU_CN它的进位输出 CN4 接到高 4 位 ALU_H4B 的进位输入 CN。这样低 4 位运算产生的进位直接参与高 4 位的运算。这种串行进位结构延迟比并行进位大但实验只做 8 位、只跑两片延迟完全可以接受而且电路结构更直观你一眼能看出进位从哪来、往哪去。参与运算的两个 8 位数据从 LINKBUS 输入。控制端分两组S3S2S1S0 决定选择哪种函数M 决定是算术运算还是逻辑运算CN 是算术模式下的进位输入。M0 时走算术表M1 时走逻辑表。逻辑运算不关心进位所以 CN 在逻辑模式下不参与算术模式加法和减法对进位的要求完全不同减法实际是“A 加 B 取反再加 1”的补码操作。3.2 实验中的四组控制组合实验直接指定了四组组合对照 74LS181 真值表就能复现。注意表里的“加”是算术和“”是逻辑或S3S2S1S0MCN运算含义100101A 加 B算术和011000A 减 B算术差101100A·B逻辑与000101AB逻辑或这四组是实验的“标准动作”。实际拨码时S 和 M、CN 分别接在实验台的不同拨键上设置顺序无所谓但要确保拨完后再让 ALU 输出使能否则总线上会出现中间态。3.3 用 Python 复现 0xAA、0x55 的四组运算实验用 A0xAA、B0x55。为什么选这两个数因为 0xAA10101010和 0x5501010101每一位互补逻辑与结果恒为 0、逻辑或结果恒为 1进位和符号特征非常明显。可以用一小段 Python 把四种运算和标志位都算出来def add8(A, B): r (A B) 0xFF CF 1 if (A B) 256 else 0 # 无符号进位 ZF 1 if r 0 else 0 SF 1 if (r 0x80) else 0 # 最高位 return r, CF, ZF, SF def sub8(A, B): r (A - B) 0xFF CF 1 if A B else 0 # 无符号借位 ZF 1 if r 0 else 0 SF 1 if (r 0x80) else 0 return r, CF, ZF, SF A, B 0xAA, 0x55 print(A加B:, add8(A, B)) print(A减B:, sub8(A, B)) print(A·B :, (*((A B) 0xFF, 0, 1 if (A B) 0 else 0, 1 if ((A B) 0x80) else 0),)) print(AB :, (*((A | B) 0xFF, 0, 1 if (A | B) 0 else 0, 1 if ((A | B) 0x80) else 0),))add8先算 8 位截断结果再分别判断进位、零、符号sub8的 CF 表示无符号减法是否需要借位。逻辑运算中 CF 固定按 0 处理因为 M 一旦切到逻辑模式进位链就不再参与。运行后A 加 B 得到 0xFFSF1A 减 B 得到 0x55三个标志位都是 0A·B 得到 0x00ZF1AB 得到 0xFFSF1。这些值与实验指导书里记录的完全一致。3.4 结果折射出的真值表特点0xAA 加 0x55 时最高位没有产生进位CF0但结果 0xFF 的最高位是 1SF1。如果把它当有符号数看0xFF 是 -10xAA 是 -860x55 是 85-8685 确实是 -1补码运算是对的。这说明同一个加法和同一个标志位切换解释视角时含义不同SF 只在有符号视角下有“结果为负”的意义CF 只在无符号视角下有“结果溢出”的意义。再往深一层逻辑与、逻辑或的结果是由 0xAA 和 0x55 逐位运算得到的不存在“进位”的概念所以这两类运算中两个输入数本身也不区分正负。真值表里 FA、FB、F1 这类组合更特殊——结果只依赖一个输入甚至不依赖任何输入。它们看起来“没用”但串行乘法中 F1 用来探测 DRB 最低位FA、FB 用来在寄存器之间搬运数据这正好是实验第三部分要用到的技巧。4. 实验结果分析有符号与无符号、标志位的正确读法4.1 0xAA 和 0x55 的实测结果实验报告里记录的四组结果整理成一张带标志位的表控制信号 S3S2S1S0MCN运算F 输出CFZFSF100101A 加 B0xFF001011000A 减 B0x55000101100A·B逻辑与0x00不参与10000101AB逻辑或0xFF不参与01注意逻辑运算的 CF 列实验台虽然把 CF 一路锁存下来但逻辑模式下进位链是断开的CF 值没有判断意义写报告时标注“不参与”比直接抄个 0 更准确。A 减 B 的结果是 0x55最高位为 0SF0结果非零ZF00xAA 大于 0x55无符号减法不需要借位CF0。三标志位全 0 反而是最容易读的一种情况。4.2 标志位电路CF、SF、ZF 如何从硬件里来标志位不是 ALU 直接输出的而是由一个独立的锁存电路在 ALU 输出稳定后抓取的。翻译成硬件描述就是assign CF ~cn4_out; // 高4位进位输出取反CF1 表示有进位 assign ZF ~|F; // F 的所有位做或非结果为 0 时 ZF1 assign SF F[7]; // 最高位直接作为符号位cn4_out来自 ALU_H4B 的 CN4 引脚。74LS181 的进位输出是低电平有效所以外面要加一个反相器CF1 才表示“最高位产生了进位”。ZF 的电路是“或非门”只要 F 端任何一位是 1或非结果就是 0只有所有位全 0ZF 才为 1。SF 最简单直接连 F[7]。这三个标志位是在 ALU_EN 的下降沿被 74LS273 锁存的意味着读数那一刻看到的标志位是“上一次运算”的标签。如果你改了 S 或 M 但没触发锁存时钟标志位不会更新。这也是实验操作里强调“令 ALU_EN0 后再观察”的原因先把运算结果稳定到总线上再让锁存电路采集。4.3 思考题分类加减、逻辑、特殊组合实验思考题问的是三件事哪些运算把 A、B 当有符号数哪些当无符号数哪些结果只与一个输入有关哪些结果与两个输入都无关。第一个问题答案取决于 M 和运算性质。M1 时全部走逻辑表逻辑运算是按位处理的不存在符号位扩展或补码转换所有 M1 的组合都按无符号处理。M0 时加法和减法走算术表硬件本身不关心符号但补码规则让同一套加法电路既能算无符号和也能算有符号和所以算术加减既可用于有符号也可用于无符号。真正要警惕的是溢出判断CF 只对无符号加减有意义有符号加减的溢出要比较进位输入和进位输出是否一致实验台没有提供 OV 标志位这也是 74LS181 实验里最容易含糊的地方。第二个和第三个问题其实在考察真值表里的退化组合。FA 时结果只与 A 有关FB 时只与 B 有关F1 或 F0 时结果与两个输入都无关。实验中 0001、0101、1001、1111 等组合里一部分就落在这两类。这类组合看似简单却是串行乘法“用到什么就取什么”的基础判断乘数最低位时把 DRA 置 1、DRB 保持乘数做一次逻辑与ZF 就能回答“最低位是不是 1”。5. “累加-移位”串行乘法的完整执行细节5.1 二进制竖式展开与硬件对应手算乘法 10101011 × 11010101展开成竖式是 8 个部分积的错位相加。硬件不会真的保留 8 个部分积而是每轮只维护一个 16 位的“部分积”从乘数最低位开始逐位判断当前位是 1 就把被乘数加到部分积高 8 位是 0 就跳过加法然后整体右移一位让下一位乘数进入判断位置。实验台里部分积高 8 位放在 DRA低 8 位初始放乘数并逐轮右移腾位。REG_0 保存被乘数REG_1 暂存加法前后要倒腾的数据。这样设计的原因是 8 位 ALU 一次只能算 8 位加法高 8 位部分积和被乘数相加后低 8 位不能丢必须有个地方临时安置——REG_1 就是干这个的。5.2 六步循环的手动操作走读指导书给的手动乘法流程是 6 个步骤一轮循环反复执行 8 轮。逐条拆开看初始状态被乘数 X 装入 REG_00 装入 REG_1乘数 Y 装入 DRBDRA 不初始化。第 1 步ALU 执行 F1结果送入 DRA。这一步是把 DRA 置成 1为下一步探测做准备。第 2 步ALU 执行 FA·B也就是 1 与 DRB 最低位做逻辑与。看 ZFZF0 说明最低位是 1ZF1 说明最低位是 0。这正是 3.4 节提到的“用特殊组合探测数据”。第 3 步把 REG_1 打入 DRA恢复部分积高 8 位。若 ZF1说明乘数位为 0跳过加法用 FB 把 DRB 暂存到 REG_1 备用若 ZF0则乘数位为 1直接进入第 4 步做加法。第 4 步把 REG_0 的被乘数打入 DRBALU 执行 A 加 B结果写回 DRA再把 REG_1 打回 DRB把刚才挪走的数据归位。第 5 步执行 DRA→DRB 级联右移。这一步要求先给 DRB_CLK 一个上升沿再给 DRA_CLK 上升沿顺序不能反。第 6 步判断乘数位是否全部移出 DRB。没移完就再用 FA 把 DRA 的部分积高 8 位存入 REG_1回到第 1 步。注意一个容易踩坑的地方很多指导书在这里把 ZF 条件写反。逻辑上应该是“ZF1乘数位为 0时跳过加法”而不是“ZF0 时跳过”。遇到和你预期不符的结果先检查这一步的跳转条件。5.3 八轮寄存器状态跟踪以 X0xAB、Y0xD5 为例把每轮结束后的寄存器状态算出来。这里的关键是右移时 DRA 的最低位移进 DRB 的最高位同时 DRA 自身右移补 0形成一个 16 位右移链。轮次DRB 最低位是否相加DRADRB初始——0x000xD511是0x550xEA20否0x2A0xF531是0x6A0xFA40否0x350x7D51是0x700x3E60否0x380x1F71是0x710x8F81是0x8E0x47第 8 轮结束后 DRA0x8E、DRB0x47拼起来是 0x8E47十进制 36423正好等于 171×213。第 8 轮加法 0x710xAB0x11C8 位结果是 0x1C进位 1 没有被丢弃而是进入右移后的 DRA 最高位变成 0x8E 的最高位。这个进位是乘积的第 16 位属于正确结果的一部分不是错误也不是需要清零的垃圾位。5.4 用 Python 模拟实验台操作序列把上面的步骤写成 Python可以对每一步的结果做断言验证X, Y 0xAB, 0xD5 DRA, DRB, REG1 0x00, Y, 0x00 for i in range(8): lsb DRB 1 # 当前乘数最低位 if lsb 1: s DRA X DRA, CF s 0xFF, 1 if s 0xFF else 0 else: CF 0 old_dra_lsb DRA 1 DRA (CF 7) | (DRA 1) # 进位进 DRA 最高位 DRB (old_dra_lsb 7) | (DRB 1) print(fDRA0x{DRA:02X} DRB0x{DRB:02X}) assert (DRA 8) | DRB 0x8E47循环里的lsb对应实验中的 ZF 判断CF对应 ALU 进位输出。old_dra_lsb必须在 DRA 被覆盖前保存这对应硬件里“先 DRB_CLK、再 DRA_CLK”的时序DRB 要先采样到 DRA 的最低位DRA 才进行自己的移位顺序搞反就会丢位。程序输出的 0x8E47 与指导书图 2-13 一致说明整个循环模型是对的。6. 验证乘法结果时要留意的三个边界6.1 进位 CF 进入 DRA 最高位手动执行乘法时第 8 轮那两个数的和可能超过 0xFF。很多人算到 0x710xAB0x11C只把 0x1C 写进 DRA进位丢掉最后高 8 位变成 0x0E怎么也对不上 0x8E。正确做法是把进位当作右移链的最高位输入。在仿真里这个进位来自 ALU 的 CN4 经过反相后的 CF锁存后作为下一次移位的数据源。验证时先看 CF 是否为 1再看 DRA 最高位是否为 1两者应当联动。6.2 ZF 条件跳转容易被指导书写反串行乘法最绕的一步是“ZF1 时跳过加法还是 ZF0 时跳过”。从原理推乘数位为 0 不需要加被乘数所以 FDRA·DRB 的结果为 0、ZF1 时应当跳过加法。如果你的实验步骤写着“ZF0 跳转”却得不出 0x8E47多半是指导书笔误。定位方法很简单单步跑第一轮DRA 置 1 后与 0xD5 做逻辑与结果最低位是 1ZF0这是加法应该发生的一轮。如果代码跳过加法DRA 不会从 0xAB 右移出 0x55而是直接变 0两步就能看出问题。6.3 有符号乘法的扩展思路实验的串行乘法只处理无符号数。8 位有符号乘法不能直接把 0xAB 当 -85 参与累加因为右移补位规则会出错。常见做法是先记录两个乘数的符号对绝对值做无符号乘法最后根据同号得正、异号得负决定结果符号。如果你在实验台上被要求扩展有符号乘法最稳妥的顺序是先把符号位拆出来单独处理再复用这套累加-移位流程而不是去改 ALU 的进位逻辑——74LS181 的加法器本身不区分符号补码运算只是解释层的技巧。本文还有配套的精品资源点击获取
