如何在“NAND俄罗斯方块”课程设置输出标志的ALU?
-
05-09-2019 - |
题
虽然我标记此作业,它实际上是针对我对我自己做一个免费的课程。无论如何,当然被称为“从NAND闪存俄罗斯方块”,我希望有人在这里已经看到或拍摄的过程中,所以我可以得到一些帮助。我在那里,我与所提供的HDL语言建立ALU阶段。我的问题是,我不能让我的芯片正确编译。我得到的错误,当我尝试设置输出标志为ALU。我认为,问题是,我不能下标任何中间变量,因为当我只是尝试标志设置为true或基于一些随机变量(比如输入标志)假的,我不明白的错误。我知道这个问题是不是与我想,因为我使用所有的内建芯片使用的芯片。
下面是我的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芯片。我已经使用超过“出”不同的变量尝试过,但同样的问题。然后我读你不能下标中间变量。我想,也许,如果我发送的中间变量其他一些芯片,而且芯片的下标,它可以解决这个问题,但它具有相同的错误。不幸的是我不能想办法设置ZR和NG标志没有下标一些中间变量,所以我很坚持!
只要你知道,如果我用下面的替换有问题的线路,它将编译(但因为我只是用一些随机输入没有给出正确的结果):
// zr flag
Not( in=zx, out=zr );
// ng flag
Not( in=zx, out=ng );
任何人有什么想法?
修改强>这里是书的附录该课程指定如何HDL的作品。具体看部5谈到客车和说:“内部销(如上面V)可以不被加下标”
编辑:这是确切的错误我得到:“68号线,不能门的输出引脚连接到部分”。该错误消息有点混乱,虽然,因为这似乎并没有成为实际的问题。如果我刚更换 “Or8way(在= OUT [0..7],OUT = ZR1);”用 “Or8way(在=假,OUT = ZR1);”它不会产生这个错误,这是什么导致我查找在附录中,如果发现了变数,因为它是导出中间,不能下标。
解决方案 2
如大同将溶液建议是使用一个中间变量作为输入提供给另一个芯片,如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=preout, b=notpreout, sel=no, out=out,out=preout2,out[15]=ng);
这是我怎样做的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);
}
你试过:
// zr flag
Or8way(
in[0]=out[ 0], in[1]=out[ 1], in[2]=out[ 2], in[3]=out[ 3],
in[4]=out[ 4], in[5]=out[ 5], in[6]=out[ 6], in[7]=out[ 7],
out=zr1);
Or8way(
in[0]=out[ 8], in[1]=out[ 9], in[2]=out[10], in[3]=out[11],
in[4]=out[12], in[5]=out[13], in[6]=out[14], in[7]=out[15],
out=zr2);
Or( a=zr1, b=zr2, out=zr );
我不知道这是否会工作,但它似乎从看这个文件的此处。
我也想三思而后使用out
作为变量名,因为它混淆试图弄清楚这一点,关键字out
之间的差异(如“out=...
”)。
按照你编辑,如果不能下标中间值,那么就出现你将不得不执行一个单独的“芯片”,如IsZero16
这将需要一个16位的值作为输入(你的中间out
),并返回一个位指示其零内斯,你可以加载到zr
。或者你可以做一个IsZero8
芯片,但你必须再调用它,它分为两个阶段,你目前正与Or8Way
做。
这似乎是一个有效的解决方案,因为您可以强>下标输入值到一个芯片上。
和,只看错误,这可能是一个不同的问题给你建议的人。短语“无法门的输出引脚连接到部分”将意味着对我来说,你是无法将信号从输出参数接回筹码加工区。这是很有意义的从电气观点来看。
您可能会发现你要输出存入一个临时变量,并用它来同时设置zr
和out
(因为一旦信号被“送”到芯片输出引脚,它们可能不再可用)。
我们可以试试:
CHIP SetFlags16 {
IN inpval[16];
OUT zflag,nflag;
PARTS:
Or8way(in=inpval[0.. 7],out=zr0);
Or8way(in=inpval[8..15],out=zr1);
Or(a=zr0,b=zr1,out=zflag);
Not(in=inpval[15],out=nflag);
}
和然后,在ALU芯片,使用本底:
// Negate the output
Not16( in=preout, out=notpreout );
Mux16( a=preout, b=notpreout, sel=no, out=tempout );
// flags
SetFlags16(inpval=tempout,zflag=zr,nflag=ng);
// Transfer tempout to out (may be a better way).
Or16(a=tempout,b=tempout,out=out);
这里有一个还以新的芯片,但感觉清洁器
/**
* Negator16 - negates the input 16-bit value if the selection flag is lit
*/
CHIP Negator16 {
IN sel,in[16];
OUT out[16];
PARTS:
Not16(in=in, out=negateIn);
Mux16(a=in, b=negateIn, sel=sel, out=out);
}
CHIP ALU {
// IN and OUT go here...
PARTS:
//Zero x and y if needed
Mux16(a=x, b[0..15]=false, sel=zx, out=x1);
Mux16(a=y, b[0..15]=false, sel=zy, out=y1);
//Create x1 and y1 negations if needed
Negator16(in=x1, sel=nx, out=x2);
Negator16(in=y1, sel=ny, out=y2);
//Create x&y and x+y
And16(a=x2, b=y2, out=andXY);
Add16(a=x2, b=y2, out=addXY);
//Choose between And/Add according to selection
Mux16(a=andXY, b=addXY, sel=f, out=res);
// negate if needed and also set negative flag
Negator16(in=res, sel=no, out=res1, out=out, out[15]=ng);
// set zero flag (or all bits and negate)
Or16Way(in=res1, out=nzr);
Not(in=nzr, out=zr);
}