anchor.diff:  import Arbiter::*;
   
   typedef struct {
  -   Vector(2, Bit#(4)) address;
  +   Vector#(2, Bit#(4)) address;
      Bit#(32) payload;
      } DataMessage deriving(Bits);
   
   interface NocNode#(numeric type dim);
      interface PipeIn#(DataMessage) hosttonode;
      interface PipeOut#(DataMessage) nodetohost;
  -   interface Vector#(dim, PipeIn#(Bit#(width))) linkupin;
  -   interface Vector#(dim, PipeOut#(Bit#(width))) linkupout;
  -   interface Vector#(dim, PipeIn#(Bit#(width))) linkdownin;
  -   interface Vector#(dim, PipeOut#(Bit#(width))) linkdownout;
  +   interface Vector#(dim, PipeIn#(Bit#(1))) linkupin;
  +   interface Vector#(dim, PipeOut#(Bit#(1))) linkupout;
  +   interface Vector#(dim, PipeIn#(Bit#(1))) linkdownin;
  +   interface Vector#(dim, PipeOut#(Bit#(1))) linkdownout;
   endinterface
   	 
   function PipeOut#(Bit#(1)) selectoutput(SerialFIFOTX#(DataMessage) x);
  
positive.code: endfunction
  
  
  module mkNocArbitrate#(Vector#(n, Bit#(4)) id, Vector#(n, PipeOut#(a)) in, PipeIn#(a) out)(Empty);
     Arbiter_IFC#(n) arb <- mkArbiter(False);   
     for (Integer i = 0; i < valueOf(n); i = i + 1)
        rule send_request (out.notFull && in[i].notEmpty);
  	 arb.clients[i].request();
        endrule
  
negative.code: 	 
  	 
     // sources
     Vector#(TAdd#(TMul#(dim, 2), 1), PipeOut#(DataMessage)) switchin = newVector;
     Vector#(TAdd#(TMul#(dim, 2), 1), PipeIn#(DataMessage)) switchout = newVector;
     // buffers for crossbar switch
     Vector#(TAdd#(TMul#(dim, 2), 1), Vector#(TAdd#(TMul#(dim, 2), 1), FIFOF#(DataMessage))) xp = replicate(newVector);
     // temps for building switch
     Vector#(TAdd#(TMul#(dim, 2), 1), PipeIn#(DataMessage)) tmpin = newVector;
     Vector#(TAdd#(TMul#(dim, 2), 1), PipeOut#(DataMessage)) tmpout = newVector;
  
  
     for (Integer i = 0; i < valueOf(dim); i = i + 1)
        begin
  	 switchin[(2*i) + 0] = rxup[i].out;
  	 switchin[(2*i) + 1] = rxdown[i].out;
  	 switchout[(2*i) + 0] = txup[i].in;
  	 switchout[(2*i) + 1] = txdown[i].in;
        end
     switchin[radix - 1] = fromhost;
     switchout[radix - 1] = tohost;
     
  
     for (Integer x = 0; x < radix; x = x + 1)
        for (Integer y = 0; y < radix; y = y + 1)
  	 if (x != y) xp[x][y] <- mkSizedFIFOF(4);
  
     for (Integer x = 0; x < (radix - 1); x = x + 1)
        xp[x][x] <- mkDiscard();
     
     xp[radix - 1][radix - 1] <- mkSizedFIFOF(4);
     
     // create distributors
     
     for (Integer x = 0; x < radix; x = x + 1)
        begin
  	 for (Integer y = 0; y < radix; y = y + 1)
  	    tmpin[y] = toPipeIn(xp[x][y]);
  	 mkDistributor(id, switchin[x], tmpin);
        end
     // create arbiters
     for (Integer y = 0; y < radix; y = y + 1)
        begin
  	 for (Integer x = 0; x < radix; x = x + 1)
  	    tmpout[x] = toPipeOut(xp[x][y]);
  	 mkNocArbitrate(id, tmpout, switchout[y]);
        end
  
    // interface wiring
  
     interface PipeIn hosttonode = toPipeIn(fifofromhost);
     interface PipeOut nodetohost = toPipeOut(fifotohost);
     interface Vector linkupin = map(selectinput, rxup);
     interface Vector linkupout = map(selectoutput, txup);
     interface Vector linkdownin = map(selectinput, rxdown);
     interface Vector linkdownout = map(selectoutput, txdown);
  
  endmodule
  