2章ALU
HDLではif文が使えないので
if nx then x = !x
みたいなのはどうすればいいのか悩んだんですが、
単純にx = !xをあらかじめ計算しておいて、その後nxで
分岐させるというやり方で実装しました。
例えば上の例だと、
Not16(in=x,out=x2);//あらかじめ計算 Mux4Way16(a=x,b=x2,c=false,d=false,sel[0]=nx,sel[1]=false,out=x);//nxの値によってxにxかx2を代入
のようになります。
ALU回路の全体の実装は以下のようになります
CHIP ALU { IN x[16], y[16], // 16-bit inputs zx, // zero the x input? nx, // negate the x input? zy, // zero the y input? ny, // negate the y input? f, // compute out = x + y (if 1) or x & y (if 0) no; // negate the out output? OUT out[16], // 16-bit output zr, // 1 if (out == 0), 0 otherwise ng; // 1 if (out < 0), 0 otherwise PARTS: Mux4Way16(a=x,b=false,c=false,d=false,sel[0]=zx,sel[1]=false,out=x1);//zx=1ならxをゼロにする //nx=1ならxを反転する Not16(in=x1,out=nx1); Mux4Way16(a=x1,b=nx1,c=false,d=false,sel[0]=nx,sel[1]=false,out=x2); Mux4Way16(a=y,b=false,c=false,d=false,sel[0]=zy,sel[1]=false,out=y1);//zy=1ならyをゼロにする //ny=1ならyを反転する Not16(in=y1,out=ny1); Mux4Way16(a=y1,b=ny1,c=false,d=false,sel[0]=ny,sel[1]=false,out=y2); //加算とAnd Add16(a=x2,b=y2,out=addout); And16(a=x2,b=y2,out=andout); //f=1のとき加算の結果を出力、f=0のときAndの結果を出力 Mux4Way16(a=andout,b=addout,c=false,d=false,sel[0]=f,sel[1]=false,out=out1); //no=1のとき出力を反転する。 Not16(in=out1,out=out2); Mux4Way16(a=out1,b=out2,c=false,d=false,sel[0]=no,sel[1]=false,out=out3); Or16(a=out3,b=false,out=out);//出力 //出力が0かどうか判定 Or16(a=out3,b=false,out[0..7]=zr1,out[8..15]=zr2);//Or8Wayで使うために分ける Or8Way(in=zr1,out=zr3); Or8Way(in=zr2,out=zr4); Or(a=zr3,b=zr4,out=zr5); Not(in=zr5,out=zr); //出力が負ならng=1 Or16(a=out3,b=false,out[15]=ng); }