anchor.diff:     FIFOF#(Token)                          bfifo <- mkFIFOF();
      PipeOut#(Token)                        bFunnel = toPipeOut(bfifo);
   
  -   Vector#(K,FIFOF#(Bool)) firstFifos  <- replicateM(mkSizedFIFOF(ub_MulLat));
  -   Vector#(K,FIFOF#(Bool)) lastFifos  <- replicateM(mkSizedFIFOF(ub_MulLat+ub_AddLat)); 
  +   FIFOF#(Bool) firstFifo  <- mkSizedFIFOF(ub_MulLat);
  +   FIFOF#(Bool) lastFifoA  <- mkSizedFIFOF(ub_MulLat);
  +   FIFOF#(Bool) lastFifoB  <- mkSizedFIFOF(ub_AddLat); 
  +
      Vector#(K,Vector#(gatherSz,FIFOF#(Float))) accumFifos <- replicateM(replicateM(mkFIFOF1));
      Vector#(K,Reg#(Bit#(TLog#(gatherSz)))) accumFifosEnqIdxs <- replicateM(mkReg(0));
      Vector#(K,Reg#(Bit#(TLog#(gatherSz)))) accumFifosDeqIdxs <- replicateM(mkReg(0));
      Vector#(K,Reg#(Bit#(32))) firstCnts <- replicateM(mkReg(0));
  -   Reg#(Bit#(32)) lastCnt   <- mkReg(0);
  +
  +   Reg#(Bit#(32)) lastCntA   <- mkReg(0);
  +   Reg#(Bit#(32)) lastCntB   <- mkReg(0);
      Reg#(Bit#(32)) gatherCntA <- mkReg(0);
      Reg#(Bit#(32)) gatherCntB <- mkReg(0);
      Vector#(K,FIFOF#(Token)) dotfifos   <- replicateM(mkFIFOF1);
      
  -   Reg#(Bit#(TLog#(K))) chanReg <- mkReg(0);
  -   Vector#(2,FIFO#(Bit#(TLog#(K)))) chanFifos <- replicateM(mkSizedFIFO(valueOf(TMul#(gatherSz,K))));
  -
  -   function Bit#(TLog#(N)) i_v(Integer i) = fromInteger(i);
  +   Vector#(2,Reg#(Bit#(TLog#(K)))) chanRegs <- replicateM(mkReg(0));
  +   Vector#(3,FIFO#(Bit#(TLog#(K)))) chanFifos <- replicateM(mkSizedFIFO(valueOf(TMul#(gatherSz,K))));
   
      Reg#(Bit#(32)) cycles <- mkReg(0);
      rule countCycles;
  
positive.code: 
     Reg#(Bit#(32)) lastMulin <- mkReg(0);
     Reg#(Bit#(32)) lastAccin <- mkReg(0);
     Reg#(Bit#(32)) macs <- mkReg(0);
     
     let gather_phase = lastCnt == fromInteger(valueOf(K));
        
     rule mulin if (!gather_phase);
        lastMulin <= cycles;
  
        let chan = chanReg;
        chanFifos[0].enq(chan);
        chanReg <= (chan + 1);
        let a <- toGet(aFunnel).get();
        let b <- toGet(bFunnel).get();
              
        let first = a.first;
        let last = a.last;
        firstFifos[chan].enq(first);
        lastFifos[chan].enq(last);
        if (a.first != b.first)
  	 $display("****\n    Warning: a.first=%d != b.first=%d\n****", a.first, b.first);
        if (a.last != b.last)
  	 $display("****\n    Warning: a.last=%d != b.last=%d\n****", a.last, b.last);
        //if (verbose) $display("%08d label=%d mulin chan=%d first=%d last=%d", cycles-lastMulin, label, chan, first, last);
        mul.request.put(tuple2(a.v, b.v));
  `ifdef TAGGED_TOKENS
        // if (a.row==2 && b.col==0)
        // 	 $display("xxx %h %h xxx", a.v, b.v);
        tag_fifos[0].enq(tuple2(a.row,b.col));
  `endif
     endrule
  
     rule mulout if (!gather_phase);
        let chan <- toGet(chanFifos[0]).get();
        let first <- toGet(firstFifos[chan]).get();
        chanFifos[1].enq(chan);
        lastAccin <= cycles;
        if (verbose) $display("%08d label=%d mulout chan=%d first=%d", cycles-lastAccin, label, chan, first);
  
negative.code:       endrule
  
        rule finishSourceA;
  	 if (timing || verbose || verbose1) $display($format(fshow(cycles)+fshow("    sourceA[")+fshow(jint)+fshow("].finish ")));
  	 let b <- sourceA[j].finish();
        endrule
  
  