You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Nand2Tetris Memory芯片实现无限循环问题排查求助

问题分析:Memory芯片键盘读取失效的原因

你第二个实现的核心问题,是把**“地址是否属于键盘区域”“是否要向键盘写入”**这两个完全无关的信号搞混了,导致读取键盘时永远拿不到正确的输入,触发了测试中的无限循环。

先看正确逻辑里的canBeKbd

在第一个能正常工作的实现中,canBeKbd是这么生成的:

And(a=address[13], b=address[14], out=canBeKbd);

这个信号的唯一作用是判断当前访问的地址是不是键盘的专属地址——键盘的基地址是0x6000(二进制1100000000000000),对应地址的第13、14位(从0开始计数)都是1。这个判断只和地址有关,和load信号完全没关系,因为键盘是只读设备,读取它根本不需要load

再看你错误实现的问题

你在第二个实现里,把DMux4Wayd输出直接赋值给了canBeKbd

DMux4Way(in=load, sel=address[13..14], a=ram1, b=ram2, c=loadScreen, d=canBeKbd);

DMux4Way的作用是根据地址最高两位,把load信号分配给不同的存储设备:只有当地址最高两位是11(键盘区域)load1时,d输出才是1,其他情况都是0

但问题来了:

  • 测试中读取键盘的时候,load信号是0(因为是读操作,不是写),这时候d输出就是0,导致后续的isKbdAnd(a=canBeKbd, b=allZero012))永远为0
  • 最后那个Mux16就会选择false(全0)作为outKbd,而不是实际的键盘输入值。程序一直读不到Y键的输入,自然就陷入无限循环了。

正确的做法总结

  • canBeKbd必须由地址的最高两位做与运算得到,只用来判断地址是否属于键盘区域,和load无关;
  • DMux4Wayd端口应该是一个被忽略的信号(比如命名为ignored,像第一个实现那样),因为键盘是只读的,永远不需要执行写入操作。

内容的提问来源于stack exchange,提问作者Thiago Miranda

火山引擎 最新活动