简介:这是一份高校计算机组成原理课程的实验教程(PDF),主要面向计算机类专业本科生,以及需要动手做运算器实验的初学者,用来掌握运算器的内部结构与工作原理。整个资源包只有1个PDF文件,大小约1.63MB,内容涵盖实验系统硬件布局、实验注意事项、实验目的、设备、原理和步骤,结构完整。教程以基本运算器实验为例,细致讲解算术、逻辑、移位三个运算部件怎样接收暂存器A、B的数据,并通过S3⋯S0、CN等控制信号选择运算结果,同时介绍了进位标志FC、零标志FZ的产生条件。文中还给出运算器逻辑功能表和详细接线图,能帮助读者理解CPLD内部集成运算器的信号连接以及实验箱操作要领,适合课前预习和课中对照。该资料目前已有243人浏览学习,对快速了解实验全貌和降低上机门槛有明显帮助。
1. 计算机组成原理实验教程(2016):为什么实验课才是挂科重灾区
「计算机组成原理」这门课有个很反直觉的现象:理论期末能考 90 分的人,进了实验室第一个存储器实验,往往坐到天黑都点不亮一块 RAM。道理不复杂——理论考的是「知道」,实验考的是「让信号在正确的时间到达正确的位置」。这个 2016 版实验教程围绕一台可观测的模型机展开,把存储器、ALU、寄存器堆和控制器串成一条完整的数据通路,适合正在上这门课、准备复试,以及把「计算机组成原理数据相关结构相关」考点背熟却没摸过硬件的同学。它不负责讲透整本教材,只负责帮你把抽象概念「落」在实验箱上;而恰恰是这一步,最容易让人翻车。就算以后只写软件,这套时序感也会在操作系统与体系结构课程里反复向你讨债。下面按实验箱上手的真实顺序讲:先认设备,再逐个啃存储器、进位链、数据通路,最后给一套排错和验收清单,照着做,至少能让你在实验课上不处于「不知道下一步该干嘛」的状态。
2. 拿到实验教程先别急着连杜邦线:实验箱认知与最小系统准备
2.1 先对教程目录,再对芯片型号:不同实验箱版本差异在哪
2016 版教程最大的坑,是它按某一款具体实验箱写的。不同学校采购的实验箱,要么是 FPGA 加外围芯片的「软核模型机」,要么是纯门电路搭的「硬布线模型机」:前者改程序就能改逻辑,后者要照着原理图一根根跳线。拿到旧教程的第一件事,不是翻正文,而是打开目录和附录里的接线表,比对实验室实际箱体上的丝印,把「教程命名」和「实体位置」的对应关系先定下来。
具体做法三步:
- 翻开实验箱盖,拍照记录主控芯片型号、拨码开关个数、LED 和数码管的位置;
- 对照教程附录的引脚连接表,确认教程里的「K1」「LED0」「DP0」对应实体箱哪个位置;
- 如果对不上,优先以箱体贴纸为准,在实验报告中把那页贴纸拍照存档。
别小看这一步。很多实验做不出来,不是逻辑写错,而是把「教程的 K3」接到了「实际箱体的 K7」上。表 1 是我常用的一张对应关系速查表模板,动手前先补完它。
| 教程命名 | 实际丝印 | 连接目标 | 确认方式 |
|---|---|---|---|
| K1~K4 | 拨码开关 SW1~SW4 | 输入信号低四位 | 万用表通断档测引脚与 GND |
| LED0~LED7 | 8 位 LED 灯组 | 输出信号显示 | 下载程序后手动置位验证 |
| DP0/DP1 | 数码管位选 | 段码/位选信号 | 用静态显示测试例程验证 |
| CLK_50M | 晶振输出 | 全局时钟引脚 | 用示波器测频率是否为 50 MHz |
这张表的价值在于:它把「教程的抽象命名」和「箱体的物理位置」之间那层黑匣子提前揭开。在实验开始时补全这张表,后续每个实验能省下半小时以上的查线时间。如果箱体丝印模糊,我一般会在实验报告里明确写「以箱体贴纸编号为准」,避免验收时被追问「你这根线接的是哪儿」。
需要强调的是,2016 这个版本配的实验箱很多已经停产,学校用的可能是改款。改款通常只换了芯片封装或扩展板位置,核心地址映射不变,但偶尔会调换某组引脚。遇到教程与实体矛盾时,以实验室现行指导老师给出的引脚约束文件为准,教程只做参考。这个「先对号、再动手」的习惯,比任何调板技巧都重要。
2.2 最小系统实验:点亮一盏 LED 背后的时钟与复位参数
实验教程的第一章通常不是「跑马灯」,而是「最小系统验证」:让板上一个 LED 按固定频率闪烁。它的目的不在 LED,而在三条硬性指标:电源上电后各级电压正确;晶振起振,全局时钟引脚能收到稳定方波;复位链路有效,按下复位键后系统能回到确定的初态。三条都过了,后续实验才有基础。
做这一步时,我一般会先把分频参数算清楚。实验箱常见主时钟是 50 MHz,若希望 LED 以约 0.5 Hz 翻转,即亮灭各 1 秒,需要把时钟分到 0.5 Hz,也就是每 100,000,000 个时钟沿翻转一次。参数上最常见的错误是把「周期」和「频率」混在一起:50 MHz 的周期是 20 ns,半周期是 10 ns,翻转一次 LED 需要的计数值是 100_000_000,而不是 50_000_000。分频逻辑本身不难,难的是脑子里先有这个换算。
复位参数同样要量化。教程建议的复位时间通常不小于 1 ms,换算到 50 MHz 时钟下就是至少 50,000 个时钟周期保持有效。用实验箱自带的复位按键时,按键按下时间远大于 1 ms,基本不用操心;但如果用程序控制复位,比如在某个异常条件触发的软复位里,就必须显式计数保证复位宽度,否则容易复位不彻底,出现「看起来复位了、跑一会又出现脏数据」的现象。
实验报告的参数记录,我自己的习惯是:电源电压、时钟频率、复位宽度、LED 目标频率这四项必须填写,并在报告里注明测量工具和档位。不要只写「正常」,这既是对自己负责,也方便后续实验出问题时回溯参数。毕竟实验课的分数构成里,过程记录常常比结果截图更值钱。
2.3 实验报告模板要提前搭:把数据记录表留白
很多人写实验报告是在实验结束当晚补,这是低效做法。比较实用的做法是动手前先把报告框架建好,留下待填的空位,一边做一边填。针对「计算机组成原理实验教程」这类课程,报告通常包含四段:实验目的、原理框图与关键信号、操作步骤与数据记录、结果分析。
我会在实验前把「原理框图与关键信号」画好,用表格列出输入、输出、时钟、复位、使能信号及其预期状态。例如一个寄存器堆实验,信号表可以是:
| 信号 | 方向 | 位宽 | 预期功能 |
|---|---|---|---|
| clk | 输入 | 1 | 全局时钟,上升沿写入 |
| rst_n | 输入 | 1 | 低电平复位全部寄存器为 0 |
| we | 输入 | 1 | 写使能,高电平允许写入 |
| addr_a/addr_b | 输入 | 5 | 双读口地址 |
| addr_w | 输入 | 5 | 写口地址 |
| data_in | 输入 | 32 | 写入数据 |
表格的好处是验收时考官问任何一路信号,你都能三秒内答出它应该是什么、实际测到是什么。这张表也是「数据记录表」的一部分。做到这一点,至少能保证你的报告不出现「数据表空白、只贴一张照片」的尴尬场面。
3. 存储器实验:把 RAM 读写时序跑通,才算跨过第一道门槛
3.1 存储器三层结构:教材存储框图到实验箱真实器件之间差了什么
「计算机组成原理存储器」这块在理论考卷上是常规考点:Cache、主存、辅存,组相联映射,替换算法。到实验箱上,你会发现抽象层次完全是另一回事。实验教程里的存储器实验一般分三个递进版本:只做一个片内 RAM 的读写测试,验证地址、数据、写使能时序;在片外 SRAM 芯片上做读写,涉及总线宽度和读写时序参数;把存储器挂到模型机总线上,配合 CPU 的取指与数据访存。
新手最常见的误区,是直接把理论教材里的 Cache 结构搬进实验报告。但实验教程本阶段根本不涉及 Cache 替换策略,做的只是最底层的 RAM 读写。理论考的是「Cache 与主存的数据流动关系」,实验考的是「地址写完多长时间数据才有效」,两者关系密切,测量手段完全不同。做存储器实验前,我建议先把教材第 4 章存储器层次结构那部分的框图重画一遍,标注出「本次实验操作的是哪一层、哪些信号由 CPU 给出、哪些由存储器给出」,然后再去碰实验箱。
3.2 用 Verilog 写一个单端口 RAM 读写控制:代码与参数说明
大部分实验箱的片内 RAM 可以直接用开发工具的 IP 核生成,但实验教程通常要求先明白底层原理,所以我会先手写一个最简单端口 RAM 做实验基线:
module ram_simple ( input wire clk, input wire rst_n, input wire [9:0] addr, // 10 bit 地址,深度 1024 input wire [7:0] din, // 8 bit 写数据 input wire we, // 写使能,高电平有效 output reg [7:0] dout // 读数据 ); reg [7:0] mem [0:1023]; // 1024 * 8 bit 存储阵列 integer i; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin // 复位时清零,便于后续仿真比对 for (i = 0; i < 1024; i = i + 1) mem[i] <= 8'b0; dout <= 8'b0; end else if (we) begin // 写数据:地址写入,且读端口也同步输出写入值 mem[addr] <= din; dout <= din; end else begin // 读数据:这里采用时序读,方便抓波形 dout <= mem[addr]; end end endmodule逻辑说明:写使能we为高时,在时钟上升沿将din写入addr指向的单元,同时读端口直接看到写入值;we为低时,读端口在下一个时钟沿输出地址对应数据。rst_n低电平复位把所有存储单元清零,这在仿真阶段会牺牲一点综合性能,但能保证每次实验都在确定初态开始。
参数上最需要调的是位宽和深度。实验教程里的数据总线常见 8 位、16 位,地址位数决定容量:10 位地址就是 1 KB,16 位地址就是 64 KB。如果测试数据出现首地址正常、高位地址乱码,多半是「地址总线高位没有接到 RAM 的地址脚」,不是 RAM 本体坏了。这个排查思路对 3.3 里的扩展实验同样适用。
上板操作我通常按四步走:先综合并分配引脚,此时不接任何外围,看片上资源是否通过;再在仿真器里写一段激励,依次写地址 0x00~0x0F 为「0~15」,再全部读回比对;然后用实验箱的手动拨码做地址与数据,观察 LED 显示;最后测量写使能信号的建立时间,确认满足芯片手册要求的最小脉宽。
3.3 存储器扩展实验:位扩展与时序参数的三个典型问题
教程第二部分通常是字扩展或位扩展,常见做法是两片 8 位 RAM 拼 16 位,或两片 1 KB RAM 拼 2 KB。位扩展相对简单,只要把地址、写使能并联,数据线一组接低八位、一组接高八位。字扩展则要引入「片选信号」,用最高位地址区分访问哪一片。这个实验里最常见的三个典型问题:
- 现象:写低字节后高字节也被改变。原因:两块芯片被同时选中,写使能并联后相当于一次写两片。解决:检查片选译码,不访问的片区片选必须置为无效电平。
- 现象:读取数据时低八位正确、高八位全为 0。原因:高字节片的读写控制引脚或片选接反。解决:先把两片的数据线都拨到 LED 上,单独给高字节片一个固定地址,轮流写 0x55 和 0xAA,看 LED 是否跟随变化。
- 现象:仿真通过、上板后第一个周期丢数据。原因:扩展后的地址信号经过了额外译码延迟,导致写使能有效时地址还未稳定。解决:检查地址建立时间是否满足要求,必要时在片选译码输出加一级寄存器再进 RAM。
这三个问题几乎覆盖了存储器实验里能遇到的「玄学」现象。凡是「仿真都对、上板就废」的,优先从时序余量角度查,而不是反复怀疑代码逻辑。
4. 数据通路与组间串行进位:从加法器到一条指令的完整执行
4.1 组间串行进位为什么是必做实验:不只是一个全加器
热词里的「组间串行进位」,在一些教材里也叫「分组串行进位」,是 ALU 实验的一个变体:把 8 位加法器按每 4 位一组,低位组的进位输出C4作为高位组的进位输入。这个设计在真实 CPU 里不会被用于关键路径,因为它链路过长,但在教学实验里几乎是必考内容——它直接考察你对进位产生与传递的理解。
「计算机408」里那道 24 年 45 题也好,二十套试题库里的 ALU 题也好,本质上都在考同一件事:加法器进位链的延迟由哪几段组成、如何用超前进位缩短。称它为「计算机组成原理组间串行进位」的经典落点,毫不为过。
实现上,我建议先用行为级代码把功能仿真跑对,再手工搭进位链结构。因为实验教程的着眼点是「能观测到进位一级一级传过去」,所以代码里不建议直接用a + b了事,而是把每一级的 carry 都引出来,方便在示波器上观测。
4.2 用 Verilog 实现 8 位组间串行进位加法器:代码、进位链与仿真
下面是我在实验室常用的一份代码,故意不用流水线,保持结构清晰:
module ripple_carry_top ( input wire [7:0] a, input wire [7:0] b, input wire cin, output wire [7:0] sum, output wire cout ); wire c3, c7; // c3:低4位进位输出;c7:高4位进位输出 // 低4位加法器,组内使用全加器逻辑 assign {c3, sum[3:0]} = a[3:0] + b[3:0] + cin; // 高4位加法器:c3 作为本组的进位输入,即组间串行 assign {c7, sum[7:4]} = a[7:4] + b[7:4] + c3; assign cout = c7; endmodule逻辑说明:{c3, sum[3:0]}这种写法把加法结果拆成进位输出加四位和,高位组把c3当作自己的cin,就形成了组间串行进位链。如果要手写全加器展开,可以把低四位a[0]^b[0]^cin之类的表达式逐级列出来,但在我做过的实验箱上,用行为级加法加进位拆分,功能完全等价,且更容易被验收老师接受。
参数说明:当数据宽度超过 8 位时,建议每组宽度保持一致,4 位或 8 位均可,并用参数GROUP_WIDTH控制,而不是硬编码在表达式里。如果实验要求测量进位链延迟,可在关键信号c3上加输出引脚,用示波器对比cin到c3、c3到cout两级延迟。需要提醒的是,在 FPGA 上测这些内部信号,得先把它们引到空闲引脚,这不是「加一行代码」的事,而是引脚规划的事,具体留给 5.1 细说。
4.3 让指令真正「跑」起来:单步时钟与数据通路观测
加法器实验之后是数据通路实验:寄存器堆、ALU、控制器三者连成循环。这一步的操作难度不在代码,而在「让一个指令周期可被肉眼观测」。由于 50 MHz 时钟太快,必须做两件事:把主时钟分频成单步模式,每按一次按键推进一个时钟沿;把 PC、IR、ALU 输出同时送到数码管或 LED,形成「现场显示」。
单步时钟的按键如果不做消抖,一次按下会产生多个触发沿,指令会连跳几步。最简单有效的消抖方式是连续采样按键电平,稳定 20 ms 后再产生一个脉冲。这个 20 ms 是针对机械按键的经验值,多数教程也采用类似指标。如果没有示波器验证,单靠肉眼反复按,很难看出毛刺影响,所以这一步会被很多初学者归为「玄学」,实际是抖动没滤干净。
数据通路实验的记录表,我用得顺手的是「PC + 指令 + 寄存器写地址 + ALU 结果」四列,每按一次单步填一行。填到十行左右,一条指令从取指到写回的完整链路就清清楚楚,实验报告的「结果分析」部分也有了素材。这里要注意控制器信号RegWrite是否在写回周期真正拉高——很多「数据通路实验值全对但寄存器没变化」的报告,问题都出在这,而不是出在 ALU 上。像头歌这类在线实训平台上的题目,也是同一个思路的变体:平台能验证仿真正确性,但真实的时间余量问题,还是要回到板子上才能暴露。
5. 实验排错避坑:示波器、引脚分配与时钟毛刺的五个典型问题
5.1 引脚分配对不上:现象、原因与解决
现象:程序下载成功,LED 不亮;或该亮的灯不亮、不该亮的常亮。
原因:综合工具里引脚约束用的是教程示例,与实验室箱体丝印不一致。常见于改款实验箱,或教程附录只给了功能名没给封装脚号。
解决:先查工程里的约束文件(.ucf/.xdc/.qsf),逐一核对信号与实际丝印;再用一根杜邦线手动把 LED 引脚接到 GND,验证丝印与物理位置的对应关系。不要靠记忆,记录在 2.1 的表 1 里最稳妥。
5.2 复位后状态没回到初态:异步复位与同步释放
现象:按下复位键时寄存器被清零,但松开按键后第一个时钟沿出错,仿真又完全正常。
原因:复位信号在按键释放时存在毛刺,异步复位逻辑只清掉了部分寄存器,产生竞态。
解决:把复位方式从纯异步改成「异步复位、同步释放」。做法是在第一级触发器里用posedge clk or negedge rst_n采样复位信号,先把复位本身打一拍,再送进后续逻辑。代码修改量很小,但能解决大多数「复位不完全」类问题。
5.3 示波器测不到波形:探头倍率与触发电平
现象:用示波器探测 CLK 引脚完全没有方波,或只有一条直线,调别的引脚却又正常。
原因:一是探头档位选在 10x/1x 与示波器通道设置不一致,垂直幅度显示错误;二是触发电平设置高于信号高电平,导致无法稳定触发。
解决:先把探头旋到 1x,示波器通道菜单里也设成 1x;再按 AUTO 键自动触发,确认频率读数接近预期;如果要用 10x 挡,必须同时改通道倍率,否则幅度读数会缩水十倍。测量数字信号时建议把触发方式设为「边沿」而非「脉冲」,减少误触发。
5.4 下载成功但灯不亮:把「没烧进去」和「没接好」分开排查
现象:下载工具提示 Done/Success,板的 LED 无任何反应。
原因:常见有四种:工程里输出信号没约束到 LED 引脚;引脚约束了但电平标准不匹配,LVTTL 与 LVCMOS33 混淆;复位引脚悬空导致系统一直处在复位态;时钟没进来。
解决:按「时钟 → 复位 → 引脚 → 逻辑」四步从硬件侧向前排查。先测时钟引脚有无波形,再量复位脚电平,再看引脚约束,最后才怀疑代码逻辑。这个顺序能快速缩小范围,也是我调试时最常用的路径。
5.5 仿真通过但板子翻车:时序约束缺失与信号竞争
现象:行为仿真完全正确,烧到板上后数据偶尔错位,错误与输入组合有关。
原因:工程缺少时序约束,综合工具按默认频率布线,关键路径未满足时序要求;或两个信号同时改变引发竞争,读到了中间态。
解决:为全局时钟添加约束,明确时钟频率;在代码里避免依赖组合信号的边沿,尽量让所有控制信号在时钟沿处同时更新。实验教程一般不要求做静态时序分析,但「加时钟约束」这一步,建议从第一个实验就养成习惯,拖到最后迟早要补课。
6. 从及格到高分:验收问答与实验报告的自测清单
6.1 用自测清单在验收前把分数挣稳
实验课的最后一道门槛不是实验本身,而是验收问答。我从历届提问里总结出三组高频问题,基本能覆盖:一是「你的指令是怎么一步步执行的」;二是「某根信号为什么是低有效」;三是「换一种时钟频率还能不能工作」。前两个考理解,第三个考参数敏感性。如果能在验收前做一遍自测,效果远比临场硬背好。
我给自己的习惯是:把每个实验的波形截图、关键信号测量值整理成一张 A4 打印稿,用彩笔标出三条关键跳变沿——时钟上升沿、写使能高电平、复位释放。验收老师看到你手里有打印稿而不是手机相册,第一印象就不同。再把单步时钟和状态显示留着,演示时用「单步模式」跑一条取指指令,口述「PC 先给出地址、存储器返回指令、IR 锁存、控制器拉高写使能」。这一套说下来,即使某个数字在实验过程中有偏差,老师也知道你不是背出来的,而是亲手调过的。
回头看这几年,我最后悔的一件事是早期所有实验报告都是「做完再写」,出错全靠回忆。后来改成「先搭表、边做边填」,同样的实验,崩溃感少了很多,报告里也不再有编数据的冲动。反过来看,如果连最小系统都没跑通就直接冲存储器实验,大概率会在接线和引脚上浪费两节课。这门课值得投入的份额,应该先放在「把第一个实验做扎实」上,希望帮到你。
本文还有配套的精品资源,点击获取