%i   "fa_inst.sfl"

submod_class   fa_inst {
   input   a,b,ci ;
   output  sum,co ;
   instrin    do ;
   instr_arg do(a,b,ci) ;
   }

module   alu {
   input      a<4>,b<4>,ci ;
   output     sum<4>,co ;
   tmp        ca,cb,cc,cd ;
   tmp        sa,sb,sc,sd ;
   tmp        tmp<4> ;
   instrin add ;
   instrin or ;
   instrin and ;
   instrin xor ;

   fa_inst    fa0,fa1,fa2,fa3 ;

   instruct add par {
      ca = fa0.do(a<0>,b<0>,ci).co ;
      cb = fa1.do(a<1>,b<1>,ca).co ;
      cc = fa2.do(a<2>,b<2>,cb).co ;
      cd = fa3.do(a<3>,b<3>,cc).co ;
      sa = fa0.do(a<0>,b<0>,ci).sum ;
      sb = fa1.do(a<1>,b<1>,ca).sum ;
      sc = fa2.do(a<2>,b<2>,cb).sum ;
      sd = fa3.do(a<3>,b<3>,cc).sum ;
      co = cd ;
      sum = sd || sc || sb || sa ;
      }
   instruct or par {
      co  = 0b0 ;
      sum = ( a<3> | b<3> ) || ( a<2> | b<2> )
            || ( a<1> | b<1> ) || (a<0> | b<0> ) ;
      }
   instruct and par {
      sum = ( a<3> & b<3> ) || ( a<2> & b<2> )
            || ( a<1> & b<1> ) || (a<0> & b<0> ) ;
      co  = 0b0 ;
      }
   instruct xor par {
      sum = ( a<3> @ b<3> ) || ( a<2> @ b<2> )
            || ( a<1> @ b<1> ) || (a<0> @ b<0> ) ;
      co  = 0b0 ;
      }
    }