anchor.diff:  import GetPut::*;
   import ClientServer::*;
   import CtrlMux::*;
  +import Gearbox::*;
  +import Clocks::*;
   
   import MIFO::*;
   import Pipe::*;
  
positive.code: endmodule
  
  module mkSharedMemoryIndicationPortal#(PipePortal#(numRequests, numIndications, 32) portal,
  				    MemreadServer#(64) readEngine,
  				    MemwriteServer#(64) writeEngine,
  				    Reg#(Bit#(32)) sglIdReg,
  				    Reg#(Bool)     readyReg)(SharedMemoryPortal#(64));
        // read the head and tail pointers, if they are different, then read a request
        Reg#(Bit#(32)) indLimitReg <- mkReg(0);
        Reg#(Bit#(32)) indHeadReg <- mkReg(0);
        Reg#(Bit#(32)) indTailReg <- mkReg(0);
        Reg#(Bit#(16)) wordCountReg <- mkReg(0);
        Reg#(Bit#(16)) messageWordsReg <- mkReg(0);
        Reg#(Bit#(16)) methodIdReg <- mkReg(0);
        Reg#(SharedMemoryPortalState) indState <- mkReg(Idle);
  
     let verbose = True;
  
        rule updateIndHeadTail if (indState == Idle && readyReg);
  	 readEngine.cmdServer.request.put(MemengineCmd { sglId: sglIdReg,
  
negative.code: 	 let head = indHeadReg;
  	 let tail = indTailReg;
  	 if (indState == HeadRequested) begin
  	    indLimitReg <= truncate(w0);
  	    indHeadReg <= truncate(w1);
  	    head = truncate(w1);
  	    indState <= TailRequested;
  	 end
  	 else begin
  	    if (indTailReg == 0) begin
  	       tail = truncate(w0);
  	       indTailReg <= tail;
  	    end
  	    //if (tail != indHeadReg)
  	       indState <= SendHeader;
  	    //else
  	       //indState <= Idle;
  	 end
  	 if (verbose)
  	    $display("receiveIndHeadTail state=%d w0=%x w1=%x head=%d tail=%d limit=%d", indState, w0, w1, head, tail, indLimitReg);
        endrule
  
     let defaultClock <- exposeCurrentClock;
     let defaultReset <- exposeCurrentReset;
     Gearbox#(1,2,Bit#(32)) gb <- mk1toNGearbox(defaultClock, defaultReset, defaultClock, defaultReset);
     rule send64bits;
        let v = gb.first;
        gb.deq();
        writeEngine.dataPipe.enq(pack(v));
     endrule
     rule sendHeader if (indState == SendHeader && interruptStatus);
        Bit#(16) numWords = portal.messageSize(readyChannel) >> 5;
        Bit#(16) totalWords = numWords + 1;
        if (numWords[0] == 0)
  	 totalWords = numWords + 2;
        Bit#(32) hdr = extend(readyChannel) << 16 | extend(totalWords);
        $display("sendHeader hdr=%h numWords=%d", hdr, numWords);
  
        indHeadReg <= indHeadReg + totalWords;
        messageWordsReg <= numWords;
        methodIdReg <= readyChannel;
        gb.enq(replicate(hdr));
        writeEngine.cmdServer.request.put(MemengineCmd { sglId: sglIdReg,
  						      base: extend(indHeadReg) << 2,
  						      burstLen: 8,
  						      len: extend(totalWords) << 2 });
        indState <= SendMessage;
     endrule
     rule sendMessage if (indState == SendMessage);
        messageWordsReg <= messageWordsReg - 1;
        let v = portal.indications[methodIdReg].first;
        portal.indications[methodIdReg].deq();
        gb.enq(replicate(v));
        $display("sendMessage v=%h messageWords=%d", v, messageWordsReg);
  
        if (messageWordsReg == 1)
  	 indState <= UpdateHead;
     endrule
     rule updateHead if (indState == UpdateHead);
        $display("updateIndHead limit=%d head=%d", indLimitReg, indHeadReg);
        gb.enq(replicate(extend(indLimitReg)));
        writeEngine.cmdServer.request.put(MemengineCmd { sglId: sglIdReg,
  						      base: 0 << 2,
  						      burstLen: 8,
  						      len: 2 << 2 });
        indState <= UpdateHead2;
     endrule
     rule updateHead2 if (indState == UpdateHead2);
        $display("updateIndHead2");
        gb.enq(replicate(extend(indHeadReg)));
        indState <= SendHeader;
     endrule
     rule done;
        let done <- writeEngine.cmdServer.response.get();
     endrule
  
  endmodule
  
  module mkSharedMemoryPortal#(PipePortal#(numRequests, numIndications, 32) portal)(SharedMemoryPortal#(64));
  