当前位置:  开发笔记 > 编程语言 > 正文

如何在"Nand to Tetris"课程中为ALU设置输出标志?

如何解决《如何在"NandtoTetris"课程中为ALU设置输出标志?》经验,为你挑选了3个好方法。

虽然我标记了这个作业,但它实际上是我自己做的一个免费课程.无论如何,该课程被称为"从Nand到俄罗斯方块",我希望有人在这里看过或参加过课程,这样我就可以得到一些帮助.我正处于使用提供的hdl语言构建ALU的阶段.我的问题是我无法正确编译芯片.当我尝试为ALU设置输出标志时,我收到错误.我认为问题是我不能下标任何中间变量,因为当我只是尝试根据一些随机变量(比如一个输入标志)将标志设置为true或false时,我没有得到错误.我知道问题不在于我尝试使用的芯片,因为我使用的是所有内置芯片.

到目前为止,这是我的ALU芯片:

/**
 * The ALU.  Computes a pre-defined set of functions out = f(x,y)
 * where x and y are two 16-bit inputs. The function f is selected 
 * by a set of 6 control bits denoted zx, nx, zy, ny, f, no.
 * The ALU operation can be described using the following pseudocode:
 *     if zx=1 set x = 0       // 16-bit zero constant
 *     if nx=1 set x = !x      // Bit-wise negation
 *     if zy=1 set y = 0       // 16-bit zero constant
 *     if ny=1 set y = !y      // Bit-wise negation
 *     if f=1  set out = x + y // Integer 2's complement addition
 *     else    set out = x & y // Bit-wise And
 *     if no=1 set out = !out  // Bit-wise negation
 *
 * In addition to computing out, the ALU computes two 1-bit outputs:
 *     if out=0 set zr = 1 else zr = 0 // 16-bit equality comparison
 *     if out<0 set ng = 1 else ng = 0 // 2's complement comparison
 */

CHIP ALU {

IN  // 16-bit inputs:
    x[16], y[16],
    // Control bits:
    zx, // Zero the x input
    nx, // Negate the x input
    zy, // Zero the y input
    ny, // Negate the y input
    f,  // Function code: 1 for add, 0 for and
    no; // Negate the out output

OUT // 16-bit output
    out[16],

    // ALU output flags
    zr, // 1 if out=0, 0 otherwise
    ng; // 1 if out<0, 0 otherwise

PARTS:
// Zero the x input
Mux16( a=x, b=false, sel=zx, out=x2 );

// Zero the y input
Mux16( a=y, b=false, sel=zy, out=y2 );

// Negate the x input
Not16( in=x, out=notx );
Mux16( a=x, b=notx, sel=nx, out=x3 );

// Negate the y input
Not16( in=y, out=noty );
Mux16( a=y, b=noty, sel=ny, out=y3 );

// Perform f
Add16( a=x3, b=y3, out=addout );
And16( a=x3, b=y3, out=andout );
Mux16( a=andout, b=addout, sel=f, out=preout );

// Negate the output
Not16( in=preout, out=notpreout );
Mux16( a=preout, b=notpreout, sel=no, out=out );

// zr flag
Or8way( in=out[0..7], out=zr1 );   // PROBLEM SHOWS UP HERE
Or8way( in=out[8..15], out=zr2 );
Or( a=zr1, b=zr2, out=zr );

// ng flag
Not( in=out[15], out=ng );

}

因此,当我尝试向Or8Way芯片发送'out'的下载版本时,问题就出现了.我尝试过使用与'out'不同的变量,但遇到同样的问题.然后我读到你无法下标中间变量.我想也许如果我将中间变量发送到其他芯片,并且该芯片下载它,它将解决问题,但它有相同的错误.不幸的是我只是想不出一种方法来设置zr和ng标志而不下标一些中间变量,所以我真的卡住了!

只是你知道,如果我用以下内容替换有问题的行,它将编译(但由于我只是使用一些随机输入而没有给出正确的结果):

// zr flag
Not( in=zx, out=zr );

// ng flag
Not( in=zx, out=ng );

有人有主意吗?

编辑:这是本书的附录,其中说明了hdl的工作原理.具体来看第5节谈论公共汽车并说:"内部引脚(如上面的v)可能不会下标".

编辑:这是我得到的确切错误:"第68行,无法将门的输出引脚连接到部分".但错误消息有点令人困惑,因为这似乎不是实际问题.如果我只是替换"Or8way(in = out [0..7],out = zr1);" "Or8way(in = false,out = zr1);" 它不会产生这个错误,这导致我在附录中查找并发现out变量,因为它是派生为中间变量,无法下标.



1> 小智..:

对于其他感兴趣的人,仿真器支持的解决方案是使用多个输出类似于:

Mux16( a=preout, b=notpreout, sel=no, out=out,out=preout2,out[15]=ng);



2> MahlerFive..:

Pax建议的解决方案是使用中间变量作为另一个芯片的输入,例如Or16Way.这是修复问题并调试后的代码:

CHIP ALU {

IN  // 16-bit inputs:
    x[16], y[16],
    // Control bits:
    zx, // Zero the x input
    nx, // Negate the x input
    zy, // Zero the y input
    ny, // Negate the y input
    f,  // Function code: 1 for add, 0 for and
    no; // Negate the out output

OUT // 16-bit output
    out[16],

    // ALU output flags
    zr, // 1 if out=0, 0 otherwise
    ng; // 1 if out<0, 0 otherwise

PARTS:
// Zero the x input
Mux16( a=x, b=false, sel=zx, out=x2 );

// Zero the y input
Mux16( a=y, b=false, sel=zy, out=y2 );

// Negate the x input
Not16( in=x2, out=notx );
Mux16( a=x2, b=notx, sel=nx, out=x3 );

// Negate the y input
Not16( in=y2, out=noty );
Mux16( a=y2, b=noty, sel=ny, out=y3 );

// Perform f
Add16( a=x3, b=y3, out=addout );
And16( a=x3, b=y3, out=andout );
Mux16( a=andout, b=addout, sel=f, out=preout );

// Negate the output
Not16( in=preout, out=notpreout );
Mux16( a=preout, b=notpreout, sel=no, out=preout2 );

// zr flag
Or16Way( in=preout2, out=notzr );
Not( in=notzr, out=zr );

// ng flag
And16( a=preout2, b=true, out[15]=ng );

// Get final output
And16( a=preout2, b=preout2, out=out );
}


你不必制作新芯片.只需使用多个输出,如下所示:Mux16(a = F16,b = NF16,sel = no,out = out,out [15] = ng,out [0..7] = zout1,out [8..15] = zout2); 然后在这些输出上使用Or16Way:Or8Way(in = zout1,out = zr1); Or8Way(in = zout2,out = zr2); 或(a = zr1,b = zr2,out = zr3); 不(in = zr3,out = zr);

3> mudge..:

这就是我做ALU的方式:

CHIP ALU {
IN  // 16-bit inputs:
    x[16], y[16],
    // Control bits:
    zx, // Zero the x input
    nx, // Negate the x input
    zy, // Zero the y input
    ny, // Negate the y input
    f,  // Function code: 1 for add, 0 for and
    no; // Negate the out output
OUT // 16-bit output
    out[16],
    // ALU output flags
    zr, // 1 if out=0, 0 otherwise
    ng; // 1 if out<0, 0 otherwise
PARTS:      
    Mux16(a=x, b=false, sel=zx, out=M16x);
    Not16(in=M16x, out=Nx);
    Mux16(a=M16x, b=Nx, sel=nx, out=M16M16x);

    Mux16(a=y, b=false, sel=zy, out=M16y);
    Not16(in=M16y, out=Ny);
    Mux16(a=M16y, b=Ny, sel=ny, out=M16M16y);

    And16(a=M16M16x, b=M16M16y, out=And16);
    Add16(a=M16M16x, b=M16M16y, out=Add16);
    Mux16(a=And16, b=Add16, sel=f, out=F16);

    Not16(in=F16, out=NF16);
    Mux16(a=F16, b=NF16, sel=no, out=out, out[15]=ng, out[0..7]=zout1, out[8..15]=zout2);

    Or8Way(in=zout1, out=zr1);
    Or8Way(in=zout2, out=zr2);
    Or(a=zr1, b=zr2, out=zr3);
    Not(in=zr3, out=zr);
}

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有