anchor.diff:     Vector#(numChannels, FIFO#(Bit#(EtherLen))) ringToDmaLen <- replicateM(mkFIFO(clocked_by txClock, reset_by txReset));
      Vector#(numChannels, FIFO#(EtherReq)) ringToDmaReq <- replicateM(mkFIFO(clocked_by txClock, reset_by txReset));
      Vector#(numChannels, SyncFIFOIfc#(Bit#(32)))   writeLens <- replicateM(mkSyncFIFO(valueOf(NumOutstandingRequests), txClock, txReset, defaultClock));
  +   Vector#(numChannels, Vector#(4, Reg#(Bit#(32)))) writeObjs <- replicateM(replicateM(mkReg(0)));
  +   Vector#(numChannels, Reg#(Bit#(8))) writeObjsCurIdx <- replicateM(mkReg(0));
   
      Reg#(Bit#(BurstLenSize)) writeRequestSizeReg <- mkReg(64);
      Reg#(Bit#(BurstLenSize)) readRequestSizeReg <- mkReg(256);
  
positive.code:                                                 tag: truncate(tag)
                                                  });
           endmethod
           endinterface);
     endfunction
     function PipeIn#(Bit#(dsz)) writeServerData(MemWriteEngineServer#(dsz) s); return s.data; endfunction
  
negative.code:          toPut(we.writeServers[channel].data).put(v.data);
           if (v.sop) begin     // parallalize dma
              let pktLen = findNearestMultiple(writeLens[channel].first, 16);
              let vec = writeObjs[channel];
              let idx = writeObjsCurIdx[channel];
              writeCmds[channel].enq(MemengineCmd {sglId:truncate(vec[idx]),   // TODO
              //writeCmds[channel].enq(MemengineCmd {sglId:0,   // TODO
                          base:0, 
                          burstLen: extend(writeRequestSizeReg),
                          len: pktLen,
                          tag:0
                          });
              writeLens[channel].deq;
              writeObjsCurIdx[channel] <= (writeObjsCurIdx[channel] + 1) & 'h3;
           end
        endrule
        rule transferFromFpgaReqRule (!writeProcessing);
  