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);
    
    
}