どのように私はもちろん「テトリスにナンド」でのALUの出力フラグを設定するのですか?
-
05-09-2019 - |
質問
、それは私が自由のために自分でやっているコースに実際にあります。とにかく、コースは「テトリスにナンドから」と呼ばれ、私はここに誰かを望んでいるので、私はいくつかの助けを得ることができるコースを見たり取りました。私は付属の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チップに「アウト」の添字バージョンを送信しようとしています時に表示されます。私は同じ問題で、「アウト」とは別の変数を使用してみました。その後、私はあなたが中間変数に添字することができないことを読みました。私はいくつかの他のチップに中間変数を送信した場合、私は多分考えられており、そのチップは、それを添字、それは問題を解決するだろうが、それは同じエラーを持っています。残念ながら、私はいくつかの中間変数を添字なしZrおよびNGフラグを設定するための方法を考えることはできませんので、私は本当にこだわっている!
だけ知っているので、私は次のように問題のある行を交換する場合、それがコンパイルされます(しかし、私はいくつかのランダムな入力を使用していますので、右の結果が得られていない):
// zr flag
Not( in=zx, out=zr );
// ng flag
Not( in=zx, out=ng );
誰もが任意のアイデアがありますか?
の編集:ブックののここで付録どのようにHDLの動作を指定するコースのため。具体的にバスを語ると言うセクション5を見てください:「添字されない場合があり、内部のピンを(上記のようにV)」
の編集のここで私が得る正確なエラーは:「ライン68は、一部にゲートの出力ピンを接続できません」。それは実際の問題ではないようであるため、エラーメッセージは、しかし一種の混乱です。私はちょうど交換した場合は、 "Or8wayを(=アウト[0..7]、アウト= ZR1で);" "(=偽、アウト= ZR1で)Or8way;" とそれが中間体として得られたため、添字をすることができませんでした、付録にルックアップしていることが、変数を見つけるために私をリードするものである、このエラーを生成しません。
解決 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 );
これが機能するかどうかはわからないが、この文書<のhref = "http://moodle.cornellcollege.edu/0809/file.php/944/qa218-31Oct2008を見てから意味をなさないようです。 PDF」のrel = "nofollowをnoreferrer">ここを。
私はまた、混乱が(「out
」のように)ことと、キーワードout
の違いを把握しようとしているので、変数名としてout=...
を使用して考え直すと思います。
あなたの編集後、あなたがそのような入力として16ビットの値を取る(あなたの中間IsZero16
)と1ビットを示すを返します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);
}