简介:本资源是华中科技大学网络安全学院《计算机组成原理》课程的完整实验报告,面向计算机类、信息安全专业本科生及硬件设计初学者,聚焦CPU底层实现能力培养。报告系统覆盖单周期与多周期MIPS CPU的数据通路构建、硬布线控制器与微程序控制器设计、Logisim平台实操步骤,以及sort.hex冒泡排序程序的全流程测试与性能对比分析,助力读者深入理解指令执行机制、时序控制逻辑与硬件优化权衡。资源为1个1.59MB的DOCX文档,结构清晰,含详细目录、电路图示(如取指/运算/访存通路)、控制器设计说明及实验总结与心得模块,内容完整可直接用于课程作业参考或复习复盘。目前已有1117人学习下载,是理论结合Logisim实践、贯通数据通路与控制逻辑的典型教学范例。
1. 这份《计算机组成原理实验报告》不是作业模板,而是一张可执行的CPU设计知识地图
如果你正在系统复习“CPU设计”这个硬核模块——不是零基础扫盲,也不是只看PPT划重点,而是要真正能动手搭出单周期/多周期MIPS CPU、能看懂控制信号表、能在Logisim里调通sort.hex冒泡排序、能说清为什么微程序控制器比硬布线多用767个时钟周期——那这份来自华科网安方向的实验报告,就是你目前最该拆解的「最小可行知识体」。它不讲抽象概念,全部落点在8条真实指令(lw/sw/beq/bne/add/slt/addi/syscall)上;不堆砌理论,每一步都对应Logisim中可复现的布线图(图1.5数据通路、图1.12控制信号逻辑、图1.17微程序加载);不回避玄学细节,连“SysCall停机靠PC使能端拉低”“R_TYPE = (ADD + SLT) & ~SysCall”这种血泪经验都写进正文。整份报告本质是:用一个完整闭环(设计→实现→测试→对比)把“CPU如何从取指走到写回”这件事,压缩成一张可打印、可标注、可逐行验证的知识地图。适合两类人:一是备考华科网安或同类院校计组课程的同学,直接对标实验要求查漏;二是自学数字逻辑+体系结构的开发者,把这份报告当“带注释的参考设计”,补全自己在数据通路综合、微指令编码、状态机跳转逻辑上的断点。
2. 单周期MIPS CPU:所有操作塞进1个时钟,但控制信号必须“一锤定音”
单周期CPU的设计哲学很直白:指令生命周期=1个时钟周期。这意味着取指、译码、ALU运算、访存、写回全部并行发生,没有流水线阶段划分,也没有状态保持需求。但正因如此,它的数据通路和控制器设计反而更考验对指令行为的“原子级”理解——每个控制信号必须在时钟上升沿到来前就稳定输出,且全程有效。这份报告里,单周期部分(1.2.1–1.2.2)给出了从指令集约束反推硬件结构的完整链路,我们来拆解三个关键层。
2.1 数据通路:MUX选择器是“交通指挥中心”,不是装饰品
单周期CPU的数据通路核心矛盾在于:不同指令需要的数据流向完全不同。比如:
lw $t0, 4($s0)需要:PC → 指令存储器 → IR;$s0 → ALU → 地址计算 → 数据存储器 → 写入寄存器;add $t0, $s0, $s1需要:$s0/$s1 → ALU → 结果 → 写入寄存器;beq $s0, $s1, label需要:$s0/$s1 → ALU(减法)→ 比较结果 → 控制PC跳转。
这些路径不能共用同一根线,必须通过多路选择器(MUX)动态切换。报告图1.5顶层数据通路清晰标出了5个关键MUX位置:
- ALU第一输入MUX:选择PC(用于beq/bne跳转计算)或寄存器A(用于R型/立即数运算);
- ALU第二输入MUX:选择寄存器B(R型)、符号扩展立即数(I型)、或零扩展立即数(beq/bne偏移);
- 写回数据MUX:选择ALU输出(R型/addi)、数据存储器输出(lw)、或PC+4(仅syscall,但本实验禁用);
- 寄存器写入地址MUX:选择rd字段(R型)或rt字段(I型);
- PC更新MUX:选择PC+4(顺序执行)或跳转目标地址(beq/bne)。
提示:这些MUX的选择端(Sel)全部由控制器输出的控制信号驱动。例如
AluSrcB信号为1时,ALU第二输入选立即数;为0时选寄存器B。MUX本身不产生逻辑,它只是把控制器的决策具象化为物理通路。很多初学者误以为“画出MUX就完成了通路设计”,实际漏掉了“谁来告诉MUX选哪一路”这个根本问题——答案就在下一节的硬布线控制器里。
2.2 硬布线控制器:用门电路“翻译”指令,6个译码信号是基石
单周期控制器的本质,是将32位二进制指令字,实时映射为一组布尔控制信号。报告1.2.2节将其拆解为两个层级:指令译码层(生成6个高阶信号)→ 控制信号生成层(组合出11个底层信号)。这个分层设计是避免逻辑爆炸的关键。
指令译码层:OP+Func双字段解析
指令译码不是简单查表,而是基于MIPS指令格式的硬逻辑。报告明确给出两套判断逻辑:
- I型指令(lw/sw/beq/bne/addi):仅看OP字段(表1.2),用比较器判断是否等于
0x23(lw)、0x2b(sw)等; - R型指令(add/slt/syscall):OP字段必须为
0x00,再结合Func字段(表1.3)区分具体功能。例如add的Func=0x20,slt的Func=0x2a,syscall的Func=0x0c。
由此导出6个译码信号(R_TYPE、ADDI、LW、SW、BEQ、BNE、SysCall),其中R_TYPE的生成式R_TYPE = (ADD + SLT) & ~SysCall尤为精妙——它排除了syscall(虽属R型但不写寄存器),体现了对指令语义的精准把握。
控制信号生成层:从译码信号到物理动作
有了6个译码信号,控制信号表(表1.1)就变成了逻辑表达式手册。例如:
RegWrite(寄存器写使能):需在R_TYPE、ADDI、LW指令时置1 →RegWrite = R_TYPE | ADDI | LWMemToReg(写回数据来源):仅LW指令从内存读数据 →MemToReg = LWAluOP(ALU操作类型):R_TYPE用ALU进行加/减/比较;I型用ALU计算地址或比较 → 需进一步解码Func和OP,报告图1.5 ALU内部逻辑展示了如何用Func字段的bit[5:0]生成ALUControl信号
注意:
AluOP和AluSrcB这类信号,其值不仅取决于当前指令类型,还依赖于指令的具体操作。例如beq和bne都需ALU做减法(AluOP=10),但lw需要ALU做加法(AluOP=00)。硬布线控制器的复杂度,恰恰藏在这些“同指令类型、不同ALU行为”的分支里。
2.3 易漏点:单周期设计中最容易被忽略的3个致命细节
单周期CPU看似简单,但实验中90%的失败案例都源于以下三个易漏点。它们不写在教材大标题下,却决定你能否让sort.hex跑出6,5,4,3,2,1,ffff:
易漏点①:PC更新逻辑的“默认路径”陷阱
为什么beq跳转成功后PC没变?因为单周期中PC更新由MUX控制,而MUX的默认选择(Sel=0)必须是PC+4。如果设计时只连接了跳转分支(如C),却忘了把PC+4接到Sel=0端,那么所有非跳转指令都会失效。补救方法:在Logisim中用探针监测PC输入端,确认PC+4信号始终接入MUX的0号输入口,且PCSrc控制信号在非跳转时稳定为0。易漏点②:寄存器文件写入时序的“竞争条件”
RegWrite信号在时钟上升沿触发写入,但ALU输出或内存数据必须在此刻已稳定。若ALU延迟过大(如未优化门级电路),或数据存储器读出延迟未被考虑,会导致写入错误值。补救方法:在Logisim中启用“时序仿真”模式,观察RegWrite上升沿时刻,ReadData(内存输出)和ALUResult是否已稳定;必要时在关键路径插入缓冲器(Buffer)。易漏点③:syscall停机的“使能端”误接
报告提到“syscall停机指令可直接通过连接PC寄存器的使能端将其禁用”,但很多同学把Halt信号接到寄存器WriteEnable,却忘了PC寄存器的使能端实际控制的是“是否更新PC值”。若Halt=1时PC使能被禁用,PC将锁死在当前值,但其他部件(ALU、内存)仍在运行,导致无限循环。补救方法:Halt信号必须同时切断PC更新(PC寄存器使能=0)和寄存器写入(RegWrite=0),并在Logisim中用Clock组件的Enable引脚全局暂停时钟。
3. 多周期MIPS CPU:把1个时钟切开,用状态机和微程序“分期付款”
如果说单周期是“一口吞下大象”,那么多周期就是“把大象切成七块,每天吃一块”。它牺牲了单周期的简洁性,换来了资源利用率提升和复杂指令支持能力。报告中多周期部分(1.2.3–1.2.5)的核心,是用时间换空间:把取指、译码、执行、访存、写回拆分成独立时钟周期,每个周期只激活所需部件,避免单周期中ALU、内存、寄存器同时全功率运行的功耗与布线压力。而实现这一拆分的两大技术路线——微程序控制器与硬布线控制器——构成了本章的主线。
3.1 数据通路:复用是灵魂,状态寄存器是“记忆锚点”
多周期CPU的数据通路(图1.6)与单周期有本质区别:同一硬件单元在不同周期承担不同角色。例如ALU在取指周期闲置,在R型指令执行周期做运算,在beq周期做减法比较,在lw周期计算地址。这种复用依赖于精确的状态控制,而状态信息必须被暂存——这就是状态寄存器(State Register)的作用。
报告图1.6明确标出4个关键状态寄存器:
- IR(Instruction Register):存储当前指令,生命周期覆盖取指→译码→执行全过程;
- A、B寄存器:暂存译码阶段读出的rs/rt操作数,供后续ALU使用;
- C寄存器:暂存PC+4(顺序地址)或跳转目标地址,用于beq/bne判断或PC更新。
提示:这些寄存器不是可有可无的“缓存”,而是多周期时序的强制要求。例如,若没有A/B寄存器,译码阶段读出的rs/rt值在下一个周期就会被新指令覆盖,导致ALU无操作数可用。多周期通路的布线难点,往往不在ALU或内存本身,而在这些状态寄存器的使能控制与时序对齐。
3.2 微程序控制器:用“微指令表”替代门电路,灵活性与体积的权衡
微程序控制器的思想是:把CPU的控制逻辑,变成存储在ROM中的“微指令序列”。每条微指令包含若干控制信号位(如MemWrite=1,AluSrcA=0),并指定下一条微指令地址。报告1.2.4节的微指令表(表1.15)就是这份“CPU操作手册”的原始形态。
微指令编码:16位字段的精密分配
表1.15显示,每条微指令为16进制格式(如3201),实际对应16位二进制。报告虽未明说,但根据Logisim微程序控制器组件规范,可反推出典型字段分配:
IorD(1 bit):指示下址是直接地址还是条件跳转;PCSrc(2 bits):选择PC更新源(PC+4 / 跳转地址 / 返回地址);AluSrcA/AluSrcB(各1 bit):ALU输入选择;MemToReg/RegDst/RegWrite等(各1 bit):直接映射硬件控制线;AluControl(3 bits):编码ALU操作(000=加, 001=减, 010=与, 011=或...);Next Address(4 bits):下条微指令地址(0-15)。
例如取指周期微指令3201(二进制0011 0010 0000 0001)中:
MemToReg=0(不写寄存器)RegWrite=0(不写寄存器)PcWrite=1(更新PC)IrWrite=1(写入IR)Next Address=0001(跳转到译码周期)
地址转移逻辑:从指令译码到微程序入口
微程序的灵魂在于“如何根据当前指令找到第一条微指令”。报告表1.13的“微程序入口地址表”给出了映射关系:R_Type→1111,ADDI→0010,LW→0101... 这些地址不是随意分配,而是按指令类型聚类,便于状态机跳转。其生成逻辑(表1.14)本质是最小项表达式:S3 = R_Type + ADDI + LW + BNE + SYSCALL,即所有以R型、ADDI、LW、BNE、SYSCALL开头的指令,其入口地址最高位S3均为1。
注意:微程序控制器的调试难点在于“微指令地址错一位,整个流程就崩”。例如
beq指令本应从地址1001开始,若入口逻辑算错导致跳到1000,则PC不会更新,程序卡死。务必用Logisim的“探针”逐周期监测微地址寄存器(Micro-PC)的值,与表1.13严格比对。
3.3 硬布线控制器:用状态机“硬编码”流程,速度与可读性的博弈
硬布线控制器抛弃微程序的ROM存储,改用有限状态机(FSM)直接生成控制信号。它更快(无ROM访问延迟),但设计更复杂。报告1.2.5节的状态机设计(图1.18)是典型Moore型FSM:输出仅取决于当前状态,不依赖输入。
状态定义:7个核心状态的语义化命名
报告图1.7状态变换图定义了14个状态(S0-S13),但实际核心只有7个语义化状态:
S0:取指(Fetch)S1:译码及取操作数(Decode & Read Reg)S2/S3/S4:lw指令的执行(Address Calc → Mem Read → Reg Write)S5/S6:sw指令的执行(Address Calc → Mem Write)S7/S8:R型指令执行(ALU Op → Reg Write)S9/S10:beq/bne执行(ALU Sub → PC Update)S11/S12:addi执行(ALU Add → Reg Write)S13:syscall停机
每个状态对应一个唯一二进制编码(S3S2S1S0),如S0=0000,S1=0001,S7=0111。状态转换逻辑(表1.16)即描述“在S1状态下,若当前指令是LW,则下一状态为S2”。
状态机实现:从真值表到Logisim电路
状态机设计分三步:
- 状态转换逻辑:根据表1.16,为每个次态位(N3/N2/N1/N0)写出最小项表达式。例如
N1 = ~S3&~S2&S1&S0 + ~S3&S2&~S1&S0 + S3&~S2&S1&S0 + ...(报告表1.17); - 输出逻辑:为每个控制信号(如
RegWrite)写出其在各状态下的值,再综合为逻辑表达式; - Logisim实现:用“Combinational Analysis”工具将表达式自动转为门电路,再与D触发器(存储状态)连接。
提示:硬布线控制器的调试比微程序更“黑匣子”。当CPU卡在某状态,不要只看控制信号,先用探针监测状态寄存器(S3S2S1S0)的值,确认是否按预期跳转。若状态正确但功能异常,再检查该状态下
AluControl、MemWrite等信号是否与表1.15一致。
3.4 易错点:多周期设计中3个让时钟周期数“暴增”的隐形坑
多周期CPU的测试结果(单周期224周期 vs 多周期891周期)看似合理,但若你的实测周期数远超891,大概率掉进了以下易错点:
易错点①:状态机“空转”——未处理指令译码失败
若指令译码逻辑未覆盖所有OP值(如漏掉0x0csyscall),当遇到未知指令时,状态机可能陷入S1(译码态)无限循环,因为Next State逻辑未定义。补救方法:在状态转换表中为所有未使用的OP值(如0x01,0x02)添加默认跳转(如回到S0),或在Logisim中用“Pull Resistor”将未连接输入拉至0。易错点②:微程序“地址溢出”——Next Address字段位宽不足
表1.15中Next Address为4位(0-15),但若状态数超过16(如增加更多指令),地址会溢出。例如S15的下址若为16(10000),4位字段只能存0000,导致跳回S0。补救方法:在Logisim微程序控制器组件属性中,将“Microinstruction Width”设为足够大(如20位),确保Next Address字段能容纳最大状态数。易错点③:访存指令“数据冒险”——未插入等待周期
lw指令在S2周期计算地址,S3周期读内存,但若内存响应延迟大于1周期(Logisim默认0延迟),S3读出的数据可能是旧值。补救方法:在S2和S3之间插入S2'等待状态,或在Logisim中为内存组件设置Delay=1,并确保状态机在S2后等待内存就绪信号(MemReady)再进入S3。
4. 控制器对比:微程序与硬布线,不是选择题而是“能力拼图”
当单周期CPU用“暴力并行”解决时序问题,多周期CPU则用“分时复用”优化资源。而在这之上,微程序与硬布线两种控制器,代表了两种截然不同的工程哲学:前者追求可编程性与可维护性,后者追求执行效率与确定性。报告1.4节的测试数据(单周期224周期,多周期891周期)只是表象,真正的差异藏在控制器实现细节中。理解这种差异,不是为了考试选A或B,而是构建你对“控制逻辑如何落地”的完整认知拼图。
4.1 微程序控制器:把控制逻辑“软件化”,代价是ROM访问延迟
微程序的核心优势在于抽象层级高。它把“CPU该做什么”和“硬件怎么实现”彻底分离:微指令表定义行为,ROM存储指令,状态机负责调度。这种分离带来三大实际价值:
- 易修改:修正
beq跳转逻辑,只需改微指令表中对应行的PCSrc位,无需重画门电路; - 易扩展:新增指令(如
xor)只需在ROM中添加新微程序段,并更新入口地址逻辑; - 易调试:Logisim的微程序控制器组件自带“单步执行”和“微地址监控”,可直观看到每周期执行哪条微指令。
但代价同样明显:每次状态跳转需访问ROM,引入额外延迟。报告中多周期CPU的891周期,包含了约14×63=882次微指令执行(14条指令×平均63周期),其中ROM访问占主导。若用高速SRAM替代ROM,延迟可降,但面积功耗上升。
对比思考:微程序像高级语言(C/Python),开发快但执行慢;硬布线像汇编,开发难但执行快。在FPGA原型验证阶段,微程序是首选;在ASIC量产芯片中,硬布线更常见。
4.2 硬布线控制器:用状态机“固化”流程,换来纳秒级确定性
硬布线控制器的终极目标是消除任何存储访问,所有控制信号由组合逻辑实时生成。这使其具备两个不可替代的特性:
- 零延迟:从指令输入到控制信号输出,仅经过几级门延迟(纳秒级),无ROM访问瓶颈;
- 确定性:执行时间完全由电路延时决定,不受存储器波动影响,符合实时系统要求。
报告图1.18的状态机电路,正是这种确定性的体现。其设计难点在于状态爆炸管理:14个状态需4位编码,状态转换逻辑涉及16个输入(4位现态+6个译码信号+2个ALU标志+4个其他信号),真值表达式极其庞大。报告表1.17的“最小项表达式”就是应对之道——用逻辑综合工具(Logisim的Combinational Analysis)将人工无法处理的布尔代数,自动转为最优门级电路。
关键洞察:硬布线并非“更先进”,而是“更专用”。它的控制逻辑与指令集强绑定,一旦指令集变更(如增加
mul指令),整个状态机需重构。而微程序只需增补微码。二者不是替代关系,而是互补:现代CPU常采用“微程序+硬布线混合架构”,用微程序处理复杂指令,硬布线处理高频简单指令。
4.3 控制信号一致性:跨控制器的“同一套语言”
无论微程序还是硬布线,它们输出的控制信号名称与功能必须完全一致,否则数据通路无法工作。报告表1.1的控制信号功能说明表(MemToReg, MemWrite, Beq...)就是这套“CPU控制语言”的词典。例如:
MemWrite=1在两种控制器中,都意味着“允许数据存储器写入”;AluOP=10都表示“ALU执行减法”;RegWrite=1都触发寄存器文件写入。
这种一致性是设计者主动约定的结果,而非技术必然。在Logisim中,你可以用“Subcircuit”封装一套标准控制信号接口,让微程序和硬布线控制器都作为该接口的“实现类”。这样,更换控制器时,只需替换子电路,无需改动数据通路布线——这是模块化设计的精髓。
4.4 易忽略点:测试环节中3个被低估的“验证维度”
学生常把测试等同于“跑通sort.hex”,但一份严谨的CPU设计验证,必须覆盖三个维度,缺一不可:
易忽略点①:指令覆盖率验证——不止sort.hex,还要单指令测试
sort.hex包含所有8条指令,但若某条指令(如bne)在排序中未被触发,其bug将被掩盖。补救方法:为每条指令单独编写最小测试程序(如bne_test.hex只含bne $s0,$s1,loop),用Logisim的“Hex Editor”加载,单步执行验证跳转逻辑。易忽略点②:边界条件验证——不只是正常值,更要极端值
sort.hex数据为6,5,4,3,2,1,ffff(ffff是-1的补码),但未测试0x80000000(最小负数)或0x7fffffff(最大正数)的ALU运算溢出。补救方法:在sort.hex中手动修改数据存储器内容,注入极端值,观察ALUFlags(如Zero,Overflow)是否正确置位。易忽略点③:时序稳定性验证——不只看最终结果,还要看中间态
多周期CPU在S2周期计算lw地址,S3周期读内存。若S2计算错误(如ALU输入选错),S3读出的数据必错,但最终sort.hex结果可能偶然正确(因后续指令覆盖)。补救方法:用Logisim的“Logging”功能记录每个周期的A,B,ALUResult,MemData,导出CSV用Excel分析,确认每周期数据流符合表1.7流程。
5. 实验复盘:从224到891,时钟周期数背后的性能真相与复习清单
当单周期CPU以224个时钟完成sort.hex,而多周期CPU(无论微程序或硬布线)都用了891个时钟,这个数字差不是“多周期更慢”的简单结论,而是揭示了CPU设计中性能、面积、功耗、可维护性四者的永恒权衡。224这个数字,是单周期“不惜一切代价并行”的代价:它需要ALU、内存、寄存器同时全速工作,布线复杂度指数级增长,时钟频率被迫降低(因最长路径延迟大)。891则是多周期“精打细算分时”的成果:每个周期只激活部分硬件,布线简洁,时钟频率可更高,但总周期数增加。真正的性能比较,应是224 × 单周期时钟周期vs891 × 多周期时钟周期。若单周期时钟为10ns(因布线长),多周期为2ns(因路径短),则单周期总耗时2240ns,多周期1782ns——多周期反而更快。这份报告的价值,正在于用可测量的数字,逼你直面这些底层真相。
5.1 性能对比深度拆解:不只是数字,更是设计哲学
报告1.4节的测试数据(单周期224,多周期891)需放入三个维度审视:
| 维度 | 单周期CPU | 多周期CPU(微程序/硬布线) | 设计启示 |
|---|---|---|---|
| 时钟周期数 | 224(固定,与指令无关) | 891(指令相关,lw需3周期,add需2周期) | 单周期性能“确定但低下”,多周期“可变但高效” |
| 关键路径延迟 | 极长(ALU+内存+寄存器全链路) | 较短(每周期仅1-2个部件) | 单周期限制最高时钟频率,多周期可提频 |
| 硬件资源 | 大量MUX、宽ALU、全尺寸寄存器文件 | 小ALU、窄数据通路、状态寄存器 | 单周期面积大功耗高,多周期面积小功耗低 |
关键发现:
sort.hex中lw指令占比高(冒泡排序频繁读数组),而lw在单周期中需ALU计算地址+内存读取+寄存器写入全并行,路径极长;在多周期中,这三步分摊到3个短周期,每周期路径短,故实际运行频率可能更高。224和891不是绝对优劣,而是不同优化目标下的解。
5.2 查漏补缺复习清单:一份可打印、可勾选的实战检查表
别再泛泛而谈“复习CPU设计”,用这份基于报告漏洞提炼的清单,逐项自检。每项都对应报告中的一个具体图、表或步骤,勾选即代表你已掌握该能力:
| 序号 | 复习要点 | 对应报告位置 | 自查方式(请动手验证) | 是否掌握 |
|---|---|---|---|---|
| 1 | 能手绘单周期数据通路图,标出5个关键MUX及其选择信号 | 图1.5 | 在纸上画出PC、IR、寄存器文件、ALU、内存,用箭头连接,并标注AluSrcB、RegDst等信号名 | □ |
| 2 | 能写出R_TYPE = (ADD + SLT) & ~SysCall的完整推导过程 | 1.2.2(1) | 从MIPS指令格式出发,列出ADD/Slt/Syscall的OP和Func值,用逻辑门画出该表达式电路 | □ |
| 3 | 能解释为何beq指令需要ALU做减法而非比较 | 表1.9, 图1.5 | 在Logisim中搭建beq测试电路,用探针观测ALU输出,确认其为A-B,而非A==B的布尔值 | □ |
| 4 | 能根据表1.15微指令表,手算S0(取指)的16位二进制编码 | 表1.15 | 查S0行,将IorD=0,PCSrc=01,AluSrcA=0...等字段按顺序拼接,得到0011001000000001(3201) | □ |
| 5 | 能用Logisim Combinational Analysis生成状态机电路 | 表1.16, 图1.18 | 将表1.16的“现态+输入→次态”真值表导入Logisim,用“Analyze Circuit”生成N3-N0逻辑,截图保存 | □ |
| 6 | 能定位并修复sort.hex测试中PC卡死的问题 | 1.4.1, 图1.21 | 在Logisim中加载sort.hex,单步执行,当PC停止更新时,用探针查PCSrc和PcWrite信号是否为0,修改逻辑使其为1 | □ |
| 7 | 能为addi指令单独编写hex测试程序并验证 | 1.4.1 | 用文本编辑器写addi $t0,$s0,5的机器码(0x20080005),保存为addi_test.hex,在Logisim中加载验证$t0值 | □ |
| 8 | 能解释微程序控制器中IorD位的作用及两种跳转模式 | 表1.15 | 修改S0的IorD=1,观察微地址是否变为PC+4(间接跳转),对比IorD=0时的直接地址跳转 | □ |
5.3 我的血泪教训:从“调不通”到“调得明白”的三个习惯
从第一次在Logisim里看着sort.hex的PC纹丝不动,到后来能一眼看出是RegWrite信号在S3周期没拉高,我踩过的坑比报告里的图还多。现在回头看,真正让我突破的不是熬夜debug,而是养成了三个机械但有效的习惯:
习惯①:永远先验证“信号有没有”,再查“信号对不对”
当CPU不工作,我不急着看ALU输出,而是先用探针点Clock信号,确认时钟在走;再点PC,确认PC在变;最后点IR,确认指令被正确读入。90%的“CPU不工作”问题,根源在时钟、复位或IR加载,而非复杂的控制逻辑。从那以后,我每次打开Logisim,第一件事就是放4个探针:Clock、PC、IR、Reset。习惯②:把“微指令表”和“状态图”打印出来贴在显示器边框
表1.15和图1.7是活的说明书。当状态机卡在S7,我立刻对照图1.7看S7该跳哪,再查表1.15看S7周期该输出什么控制信号,最后用Logisim探针逐个比对。纸质文档的物理存在感,比电子文档的Ctrl+F更能强迫你建立空间记忆。从那以后,我每次做实验,必打印这两页,用荧光笔标出当前调试的指令路径。习惯③:给每个子电路加“黄金测试用例”
我为ALU子电路写了add_test.hex(只含add $t0,$s0,$s1),为内存子电路写了mem_test.hex(只含lw $t0,0($s0)),为控制器写了`ctrl_test
本文还有配套的精品资源,点击获取