nand2tetris硬件模拟器芯片实现报错求助
解决nand2tetris作业中的三个芯片实现问题
芯片1:输入乘2(左移一位)
报错信息
Chip out[0] is not found in working and built in folders
问题分析
nand2tetris的HDL不支持直接在PARTS块中赋值信号(如out[0] = 0),这种写法会被工具误认为要调用名为out[0]的芯片,导致找不到对应芯片的错误。
修正代码
IN in[16]; OUT out[16]; PARTS: // 最低位补0 Constant(0, out=out[0]); // 其余位左移一位,用And与true连接等价于直接传递信号 And(a=in[0], b=true, out=out[1]); And(a=in[1], b=true, out=out[2]); And(a=in[2], b=true, out=out[3]); And(a=in[3], b=true, out=out[4]); And(a=in[4], b=true, out=out[5]); And(a=in[5], b=true, out=out[6]); And(a=in[6], b=true, out=out[7]); And(a=in[7], b=true, out=out[8]); And(a=in[8], b=true, out=out[9]); And(a=in[9], b=true, out=out[10]); And(a=in[10], b=true, out=out[11]); And(a=in[11], b=true, out=out[12]); And(a=in[12], b=true, out=out[13]); And(a=in[13], b=true, out=out[14]); And(a=in[14], b=true, out=out[15]);
说明
所有信号连接必须通过内置或自定义芯片实现:用Constant芯片生成0信号连接到输出最低位,其余位用And芯片(与true连接)直接传递输入的对应位,实现左移一位(乘2)的功能。
芯片2:统计两个输入的不同比特数
报错信息
line 6: diff[0], sub bus of an internal node may not be used
问题分析
nand2tetris的HDL不允许直接操作内部总线的单个子位(如diff[0]),试图将Xor的输出赋值给未声明的内部总线子位,违反语法规则。
修正代码
IN a[16], b[16]; OUT out[16]; PARTS: // 对每一位做异或,结果存入单独的内部节点 Xor(a=a[0], b=b[0], out=x0); Xor(a=a[1], b=b[1], out=x1); Xor(a=a[2], b=b[2], out=x2); Xor(a=a[3], b=b[3], out=x3); Xor(a=a[4], b=b[4], out=x4); Xor(a=a[5], b=b[5], out=x5); Xor(a=a[6], b=b[6], out=x6); Xor(a=a[7], b=b[7], out=x7); Xor(a=a[8], b=b[8], out=x8); Xor(a=a[9], b=b[9], out=x9); Xor(a=a[10], b=b[10], out=x10); Xor(a=a[11], b=b[11], out=x11); Xor(a=a[12], b=b[12], out=x12); Xor(a=a[13], b=b[13], out=x13); Xor(a=a[14], b=b[14], out=x14); Xor(a=a[15], b=b[15], out=x15); // 将所有异或结果相加,得到不同比特的数量 Add16(in[0]=x0, in[1]=x1, in[2]=x2, in[3]=x3, in[4]=x4, in[5]=x5, in[6]=x6, in[7]=x7, in[8]=x8, in[9]=x9, in[10]=x10, in[11]=x11, in[12]=x12, in[13]=x13, in[14]=x14, in[15]=x15, out=out);
说明
为每个Xor的输出创建单独的内部节点,再将这些节点分别连接到Add16的对应输入位。异或结果为1表示对应位不同,将所有1相加即可得到不同比特的总数。
芯片3:统计从MSB开始的连续零数量
报错信息
line 8, Can't connect gate's output pin to part
问题分析
输出引脚是单向的,不能作为其他芯片的输入信号使用。原代码中直接将out[0]作为下一个And的输入,违反了HDL的单向引脚规则;同时逻辑不符合“连续零数量”的需求。
修正代码(语法修复+逻辑调整)
IN in[16]; OUT out[16]; PARTS: // 初始化计数允许信号:MSB是0则允许计数,否则停止 Not(in=in[15], out=cnt_en0); // 每一位判断:当前位是0且之前允许计数,则继续允许计数 And(a=cnt_en0, b=Not(in=in[14]), out=cnt_en1); And(a=cnt_en1, b=Not(in=in[13]), out=cnt_en2); And(a=cnt_en2, b=Not(in=in[12]), out=cnt_en3); And(a=cnt_en3, b=Not(in=in[11]), out=cnt_en4); And(a=cnt_en4, b=Not(in=in[10]), out=cnt_en5); And(a=cnt_en5, b=Not(in=in[9]), out=cnt_en6); And(a=cnt_en6, b=Not(in=in[8]), out=cnt_en7); And(a=cnt_en7, b=Not(in=in[7]), out=cnt_en8); And(a=cnt_en8, b=Not(in=in[6]), out=cnt_en9); And(a=cnt_en9, b=Not(in=in[5]), out=cnt_en10); And(a=cnt_en10, b=Not(in=in[4]), out=cnt_en11); And(a=cnt_en11, b=Not(in=in[3]), out=cnt_en12); And(a=cnt_en12, b=Not(in=in[2]), out=cnt_en13); And(a=cnt_en13, b=Not(in=in[1]), out=cnt_en14); And(a=cnt_en14, b=Not(in=in[0]), out=cnt_en15); // 将连续零数量转换为二进制输出(示例逻辑,需根据需求补充完整) // 示例:out[0]表示数量≥1,out[1]表示数量≥2,以此类推 Or(a=cnt_en0, b=cnt_en1, b=cnt_en2, b=cnt_en3, b=cnt_en4, b=cnt_en5, b=cnt_en6, b=cnt_en7, b=cnt_en8, b=cnt_en9, b=cnt_en10, b=cnt_en11, b=cnt_en12, b=cnt_en13, b=cnt_en14, b=cnt_en15, out=out[0]); Or(a=cnt_en1, b=cnt_en2, b=cnt_en3, b=cnt_en4, b=cnt_en5, b=cnt_en6, b=cnt_en7, b=cnt_en8, b=cnt_en9, b=cnt_en10, b=cnt_en11, b=cnt_en12, b=cnt_en13, b=cnt_en14, b=cnt_en15, out=out[1]); // 其余位逻辑可按此规律补充
说明
- 语法修复:使用内部节点
cnt_en0到cnt_en15传递计数允许信号,避免直接使用输出引脚作为输入。 - 逻辑调整:
cnt_enX为1表示从MSB到当前位都是连续的0,通过Not判断当前位是否为0,And判断之前是否允许计数。 - 输出转换:需要将
cnt_en信号转换为二进制数值(可通过优先级编码器或分层Or逻辑实现),最终输出连续零的数量。
内容的提问来源于stack exchange,提问作者D00MA
相关产品推荐
相关产品推荐

