anchor.diff:  	 if (isLast)
   	    c = 0;
   	 countInReg <= c;
  -	 xyfifo.enq(tuple3(isFirst,tpl_1(tpl), tpl_2(tpl)));
  -	 if (!useMac)
  -	    firstFifo.enq(isFirst);
  +	 for (Integer i = 0; i < valueOf(N); i = i + 1) begin
  +	    let avec = tpl_1(tpl);
  +	    let bvec = tpl_2(tpl);
  +	    abfifos[i].enq(tuple3(isFirst,avec[i], bvec[i]));
  +	 end
   	 lastFifo.enq(isLast);
         endmethod
      endinterface : request
      interface PipeOut pipe = dotpipe;
      interface Reg numElts = numEltsReg;
  -endmodule
  +endmodule : mkDotProdServer
   
   
   typedef struct {
  
positive.code: 
     let n = valueOf(N);
     Bool verbose = False;
     Bool useMac = True;
  
     Reg#(UInt#(20)) numEltsReg <- mkReg(0);
     Reg#(UInt#(20)) countInReg <- mkReg(0);
     FIFOF#(Tuple3#(Bool,Vector#(N,Float),Vector#(N,Float))) xyfifo <- mkFIFOF();
     FIFOF#(Bool) firstFifo <- mkFIFOF();
     FIFOF#(Bool) lastFifo <- mkFIFOF();
     PipeOut#(Tuple3#(Bool, Vector#(N,Float),Vector#(N,Float))) xypipe = toPipeOut(xyfifo);
  
     Vector#(N, Server#(Tuple4#(Maybe#(Float), Float, Float, RoundMode), Tuple2#(Float,Exception))) macs <- replicateM(mkFloatMac);
     Vector#(N, FloatServer2#(Float)) muls <- replicateM(mkFloatMultiplier);
     Vector#(N, FloatServer2#(Float)) adders <- replicateM(mkFloatAdder);
     Vector#(N, FIFO#(Float)) accumFifo <- replicateM(mkFIFO());
     FIFOF#(Vector#(N,Float)) resultFifo <- mkFIFOF();
  
     rule mul;
        let v = xypipe.first;
        xypipe.deq;
        let isFirst = tpl_1(v);
        let x = tpl_2(v);
        let y = tpl_3(v);
  
        for (Integer i = 0; i < valueOf(N); i = i + 1) begin
  	 Maybe#(Float) accum = tagged Invalid;
  	 if (useMac) begin
  	     if (!isFirst) begin
  		accum = tagged Valid accumFifo[i].first();
  		accumFifo[i].deq();
  	     end
              macs[i].request.put(tuple4(accum, x[i], y[i], defaultValue));
  	 end
  	 else begin
  	    muls[i].request.put(tuple3(x[i],y[i],defaultValue));
  	 end
  	 if (verbose) $display($format(fshow("label=")+fshow(label)+fshow(" dotprod x=") + fshow(x) + fshow(" y=") + fshow(y) + fshow(" accum=")+fshow(pack(accum))));
        end
     endrule
  
     rule add;
        if (!useMac) begin
  	 Float accum = unpack(0);
  	 let isFirst = firstFifo.first();
  	 firstFifo.deq();
  	 for (Integer i = 0; i < valueOf(N); i = i + 1) begin
  	    if (!isFirst) begin
  	       accum = accumFifo[i].first();
  	       accumFifo[i].deq();
  	    end
  	    let resp <- adders[i].response.get();
  	    adders[i].request.put(tuple3(accum,tpl_1(resp),defaultValue));	 
  	 end
        end
     endrule
  
     rule macout;
        Vector#(N,Float) vs = unpack(0);
        let isLast = lastFifo.first();
        lastFifo.deq();
        for (Integer i = 0; i < valueOf(N); i = i + 1) begin
  	 Float vi;
  	 if (useMac) begin
  	    let resp <- macs[i].response.get();
  	    vi = tpl_1(resp);
  	 end
  	 else begin
  	    let resp <- adders[i].response.get();
  	    vi = tpl_1(resp);
  	 end
  	 vs[i] = vi;
  	 if (!isLast) begin
  	    accumFifo[i].enq(vi);
  	 end
        end
        if (isLast) begin
  	 Vector#(N,Bit#(32)) ivs = unpack(pack(vs));
  	 resultFifo.enq(vs);
  	 if (verbose) $display(fshow("label=")+fshow(label)+fshow(" isLast=")+fshow(isLast)+fshow(" numElts=")+fshow(numEltsReg)+fshow(" mul=") + fshow(ivs));
        end
     endrule
  
     PipeOut#(Vector#(N,Float)) resultPipe = toPipeOut(resultFifo);
     PipeOut#(Float) dotpipe <- mkReducePipe(mkFloatAddPipe, resultPipe);
     PipeOut#(Float) displaydotpipe = (interface PipeOut#(Float);
        method Float first(); return dotpipe.first(); endmethod
  
negative.code: import Timer::*;
  import RbmTypes::*;
  
  interface DotProdServer#(numeric type n);
     interface Reg#(UInt#(20)) numElts;
     interface Put#(Tuple2#(Vector#(n,Float),Vector#(n,Float))) request;
  