anchor.diff:  import MemTypes::*;
   import ConnectalMemory::*;
   
  -interface SharedMemoryPipeOut#(numeric type dataBusWidth);
  +interface SharedMemoryPipeOut#(numeric type dataBusWidth, numeric type pipeCount);
      interface SharedMemoryPortalConfig cfg;
  -   interface PipeOut#(Bit#(32)) data;
  +   interface Vector#(pipeCount, PipeOut#(Bit#(32))) data;
   endinterface
   interface SharedMemoryPipeIn#(numeric type dataBusWidth);
      interface SharedMemoryPortalConfig cfg;
  
positive.code:          readyReg <= True;
        endmethod
     endinterface
     interface data = toPipeOut(dataFifo);
  endmodule
  
  module mkSharedMemoryIndicationPortal#(PipePortal#(numRequests, numIndications, 32) portal,
      Vector#(2,MemReadServer#(64)) readEngine, Vector#(2, MemWriteServer#(64)) writeEngine)(SharedMemoryPortal#(64));
     let defaultClock <- exposeCurrentClock;
     let defaultReset <- exposeCurrentReset;
     // read the head and tail pointers, if they are different, then read a request
     Reg#(Bit#(16)) limitReg <- mkReg(0);
     Reg#(Bit#(16)) headReg <- mkReg(0);
     Reg#(Bit#(16)) tailReg <- mkReg(0);
     Reg#(Bit#(16)) messageWordsReg <- mkReg(0);
     Reg#(Bit#(16)) methodIdReg <- mkReg(0);
     Reg#(Bool) paddingReg <- mkReg(False);
  
negative.code:    Reg#(Bool)     readyReg   <- mkReg(False);
     MIMOConfiguration mimoConfig = defaultValue;
     MIMO#(2,1,2,Bit#(32)) readMimo <- mkMIMO(mimoConfig);
     Vector#(pipeCount, FIFOF#(Bit#(32))) dataFifo <- replicateM(mkFIFOF);
  
     let verbose = True;
  
     rule updateReqWrPtrRdPtr if (state == Idle && readyReg);
        if (verbose) $display("updateReqWrPtrRdPtr");
        readEngine[0].request.put(
            MemengineCmd {sglId: sglIdReg, base: 0, burstLen: 16, len: 16, tag: 0});
        state <= WrPtrRequested;
     endrule
  
     rule receiveReqWrPtrRdPtr if (state == WrPtrRequested || state == RdPtrRequested);
        let v <- toGet(readEngine[0].data).get();
        let w0 = v.data[31:0];
        let w1 = v.data[63:32];
        let wrPtr = wrPtrReg;
        let rdPtr = rdPtrReg;
        let limit = limitReg;
        if (state == WrPtrRequested) begin
  	 limit = w0;
           limitReg <= w0;
           wrPtrReg <= w1;
           wrPtr = w1;
           state <= RdPtrRequested;
        end
        else begin
           if (rdPtrReg == 0) begin
              rdPtr = w0;
              rdPtrReg <= rdPtr;
           end
           if (rdPtr != wrPtrReg)
              state <= RequestMessage;
           else
              state <= Idle;
        end
        if (verbose)
           $display("receiveReqWrPtrRdPtr state=%d w0=%x w1=%x wrPtr=%d rdPtr=%d limit=%d", state, w0, w1, wrPtr, rdPtr, limit);
     endrule
  
     rule requestMessage if (state == RequestMessage);
        Bit#(32) wordCount = wrPtrReg - rdPtrReg;
        if ((rdPtrReg & 1) == 1) begin
           $display("WARNING requestMessage: reqRdPtr=%d is odd.", rdPtrReg);
        end
        let rdPtr = rdPtrReg + wordCount;
        if (wrPtrReg < rdPtrReg) begin
           $display("requestMessage wrapped: wrPtr=%d rdPtr=%d", wrPtrReg, rdPtrReg);
           wordCount = limitReg - rdPtrReg;
           rdPtr = 4;
        end
        if (verbose) $display("requestMessage id=%d rdPtr=%h wrPtr=%h wordCount=%d", sglIdReg, rdPtrReg, wrPtrReg, wordCount);
        rdPtrReg <= rdPtr;
        countReg <= truncate(wordCount);
        readEngine[1].request.put( MemengineCmd
            {sglId: sglIdReg, base: extend(rdPtrReg << 2), burstLen: 16, len: wordCount << 2, tag: 0});
        state <= MessageHeaderRequested;
     endrule
  
  