fix interface

fix interface

// Copyright (c) 2014 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import XilinxCells::*;
import XbsvXilinxCells::*;
import Gearbox::*;
import Pipe::*;
import FIFO::*;
import BRAMFIFO::*;
import Vector::*;
import Clocks::*;
import DefaultValue::*;

import extraXilinxCells::*;

(* always_enabled *)
interface FMComms1DACPins;
   method Bit#(14) io_dac_data_p();
   method Bit#(14) io_dac_data_n();
   method Action io_dac_dco_p(Bit#(1) v);
   method Action io_dac_dco_n(Bit#(1) v);
   method Bit#(1) io_dac_dci_p();
   method Bit#(2) io_dac_dci_n();
   method Clock deleteme_unused_clock;
   method Reset deleteme_unused_reset;
endinterface

typedef struct {
   Bit#(16) data_i;
   Bit#(16) data_q;
   } OIQ deriving (Bits);

interface FMComms1DAC;
   interface FMComms1DACPins pins;
   interface PipeIn#(Bit#(64)) dac;
endinterface

/* This module drives an Analog Devices FMComms1
 * evaluation board Digital to Analog Converter, it accepts
 * the data as a PipeIn type on the default clock.
 * The FMComms1 supplies the DAC clock as a differential pair
 *
 * Output is double data rate, with clock supplied by the FMComms1
 * Output data is 14 bits twos-complement or offset binary
 *
 * Differential outputs are converted from single ended by using Xilinx OBUFDS
 * cells. The clock is converted to single ended by an IBUFGDS cell
 *
 * DDR data is convered from SDR using ODDR cells
 * At this point, the data is a 14 bit in-phase data signal,
 * plus a 14 bit quadrature signal, interleaved
 *
 * The SDR data is a 32-bit OIQ datatype
 *
 * The 32-bit data is converted from 64-bits by a Gearbox
 *
 * Clock conversion happens 64-bits wide using a SyncBRAMFIFO, which
 * presents a PipeIn channel to the rest of the logic.
 */

module mkFMComms1DAC(FMComms1DAC);

   Clock def_clock <- exposeCurrentClock;
   Reset def_reset <- exposeCurrentReset;
   Clock dac_dco;
   Wire#(Bit#(1)) dac_dco_p <- mkDWire(0);
   Wire#(Bit#(1)) dac_dco_n <- mkDWire(0);

   dac_dco <- mkClockIBUFDS(dac_dco_p, dac_dco_n);
   Reset dac_reset <- mkAsyncReset(3, def_reset, dac_dco);

   SyncFIFOIfc#(Vector#(2, OIQ)) outfifo <- mkSyncBRAMFIFO(128, def_clock, def_reset, dac_dco, dac_reset);

   Gearbox#(2, 1, OIQ) gb <- mkNto1Gearbox(dac_dco, dac_reset, dac_dco, dac_reset);
   ODDRParams#(Bit#(14)) oddrparams = defaultValue;
//   oddrparams.ddr_clk_edge = "SAME_EDGE_PIPELINED";
      oddrparams.ddr_clk_edge = "SAME_EDGE";

   ODDR#(Bit#(14)) dac_ddr <- mkODDR(oddrparams, clocked_by (dac_dco));

   Vector#(14, Wire#(Bit#(1))) dac_ddr_data <- replicateM(mkDWire(0));

   Vector#(14, DiffOut) dac_out = newVector;

   for (Integer i = 0; i < 14; i = i + 1)
      dac_out[i] <- mkxOBUFDS(dac_ddr_data[i]);

   Bit#(1) dac_dci_bit <- mkC2B(dac_dco);
   Wire#(Bit#(1)) dac_dci_wire <- mkDWire(0);

   rule senddown_clk;
      dac_dci_wire <- dac_dci_bit;
   endrule

   DiffOut dac_dci <- mkxOBUFDS(dac_dci_wire);

   rule senddown_gb;
      outfifo.deq();
      gb.enq(outfifo.first());
   endrule

   rule senddown_oddr;
      let d = gb.first;
      gb.deq();
      dac_ddr.d1(d[0].data_i[15:2]);
      dac_ddr.d2(d[0].data_q[15:2]);
   endrule

   function Bit#(1) foo_p(DiffOut v);
      return (v.read_p());
   endfunction

   function Bit#(1) foo_n(DiffOut v);
      return (v.read_n());
   endfunction

   function Bit#(14) get_p(Vector#(14, DiffOut) v);
      return(pack(map(foo_p, v)));
   endfunction

   function Bit#(14) get_n(Vector#(14, DiffOut) v);
      return(pack(map(foo_n, v)));
   endfunction

   interface FMComms1DACPins pins;

      method Bit#(14) io_dac_data_p();
         return(get_p(dac_out));
      endmethod

      method Bit#(14) io_dac_data_n();
         return(get_n(dac_out));
      endmethod

      method Bit#(1) io_dac_dci_p();
         return(dac_dci.read_p());
      endmethod

      method Bit#(1) io_dac_dci_n();
         return(dac_dci.read_n());
      endmethod

      method Action io_dac_dco_p(Bit#(1) v);
	 dac_dco_p <= v;
      endmethod

      method Action io_dac_dco_n(Bit#(1) v);
	 dac_dco_n <= v;
      endmethod
      interface deleteme_unused_clock = dac_dco;
      interface deleteme_unused_reset = dac_reset;

   endinterface

   interface PipeIn dac;

      method Action enq(Bit#(64) v);
	 outfifo.enq(unpack(pack(v)));
      endmethod

      method Bool notFull() = outfifo.notFull;

   endinterface

endmodule

// Copyright (c) 2014 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import XilinxCells::*;
import XbsvXilinxCells::*;
import Gearbox::*;
import Pipe::*;
import FIFO::*;
import BRAMFIFO::*;
import Vector::*;
import Clocks::*;
import DefaultValue::*;

import extraXilinxCells::*;

(* always_enabled *)
interface FMComms1DACPins;
   method Bit#(14) io_dac_data_p();
   method Bit#(14) io_dac_data_n();
   method Action io_dac_dco_p(Bit#(1) v);
   method Action io_dac_dco_n(Bit#(1) v);
   interface Bit#(1) io_dac_dci_p();
   interface Bit#(2) io_dac_dci_n();
   interface Clock deleteme_unused_clock;
   interface Reset deleteme_unused_reset;
endinterface

typedef struct {
   Bit#(16) data_i;
   Bit#(16) data_q;
   } OIQ deriving (Bits);

interface FMComms1DAC;
   interface FMComms1DACPins pins;
   interface PipeIn#(Bit#(64)) dac;
endinterface

/* This module drives an Analog Devices FMComms1
 * evaluation board Digital to Analog Converter, it accepts
 * the data as a PipeIn type on the default clock.
 * The FMComms1 supplies the DAC clock as a differential pair
 *
 * Output is double data rate, with clock supplied by the FMComms1
 * Output data is 14 bits twos-complement or offset binary
 *
 * Differential outputs are converted from single ended by using Xilinx OBUFDS
 * cells. The clock is converted to single ended by an IBUFGDS cell
 *
 * DDR data is convered from SDR using ODDR cells
 * At this point, the data is a 14 bit in-phase data signal,
 * plus a 14 bit quadrature signal, interleaved
 *
 * The SDR data is a 32-bit OIQ datatype
 *
 * The 32-bit data is converted from 64-bits by a Gearbox
 *
 * Clock conversion happens 64-bits wide using a SyncBRAMFIFO, which
 * presents a PipeIn channel to the rest of the logic.
 */

module mkFMComms1DAC(FMComms1DAC);

   Clock def_clock <- exposeCurrentClock;
   Reset def_reset <- exposeCurrentReset;
   Clock dac_dco;
   Wire#(Bit#(1)) dac_dco_p <- mkDWire(0);
   Wire#(Bit#(1)) dac_dco_n <- mkDWire(0);

   dac_dco <- mkClockIBUFDS(dac_dco_p, dac_dco_n);
   Reset dac_reset <- mkAsyncReset(3, def_reset, dac_dco);

   SyncFIFOIfc#(Vector#(2, OIQ)) outfifo <- mkSyncBRAMFIFO(128, def_clock, def_reset, dac_dco, dac_reset);

   Gearbox#(2, 1, OIQ) gb <- mkNto1Gearbox(dac_dco, dac_reset, dac_dco, dac_reset);
   ODDRParams#(Bit#(14)) oddrparams = defaultValue;
//   oddrparams.ddr_clk_edge = "SAME_EDGE_PIPELINED";
      oddrparams.ddr_clk_edge = "SAME_EDGE";

   ODDR#(Bit#(14)) dac_ddr <- mkODDR(oddrparams, clocked_by (dac_dco));

   Vector#(14, Wire#(Bit#(1))) dac_ddr_data <- replicateM(mkDWire(0));

   Vector#(14, DiffOut) dac_out = newVector;

   for (Integer i = 0; i < 14; i = i + 1)
      dac_out[i] <- mkxOBUFDS(dac_ddr_data[i]);

   Bit#(1) dac_dci_bit <- mkC2B(dac_dco);
   Wire#(Bit#(1)) dac_dci_wire <- mkDWire(0);

   rule senddown_clk;
      dac_dci_wire <- dac_dci_bit;
   endrule

   DiffOut dac_dci <- mkxOBUFDS(dac_dci_wire);

   rule senddown_gb;
      outfifo.deq();
      gb.enq(outfifo.first());
   endrule

   rule senddown_oddr;
      let d = gb.first;
      gb.deq();
      dac_ddr.d1(d[0].data_i[15:2]);
      dac_ddr.d2(d[0].data_q[15:2]);
   endrule

   function Bit#(1) foo_p(DiffOut v);
      return (v.read_p());
   endfunction

   function Bit#(1) foo_n(DiffOut v);
      return (v.read_n());
   endfunction

   function Bit#(14) get_p(Vector#(14, DiffOut) v);
      return(pack(map(foo_p, v)));
   endfunction

   function Bit#(14) get_n(Vector#(14, DiffOut) v);
      return(pack(map(foo_n, v)));
   endfunction

   interface FMComms1DACPins pins;

      method Bit#(14) io_dac_data_p();
         return(get_p(dac_out));
      endmethod

      method Bit#(14) io_dac_data_n();
         return(get_n(dac_out));
      endmethod

      method Bit#(1) io_dac_dci_p();
         return(dac_dci.read_p());
      endmethod

      method Bit#(1) io_dac_dci_n();
         return(dac_dci.read_n());
      endmethod

      method Action io_dac_dco_p(Bit#(1) v);
	 dac_dco_p <= v;
      endmethod

      method Action io_dac_dco_n(Bit#(1) v);
	 dac_dco_n <= v;
      endmethod
      interface deleteme_unused_clock = dac_dco;
      interface deleteme_unused_reset = dac_reset;

   endinterface

   interface PipeIn dac;

      method Action enq(Bit#(64) v);
	 outfifo.enq(unpack(pack(v)));
      endmethod

      method Bool notFull() = outfifo.notFull;

   endinterface

endmodule


filling out the remaining bits in tile/framework

// Copyright (c) 2013 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import Vector::*;
import Connectable::*;

import Portal::*;
import CtrlMux::*;
import HostInterface::*;
import Tile::*;
import Memread::*;
import MMU::*;
import MemServer::*;
import MemTypes::*;

import MemreadRequest::*;
import MemreadIndication::*;
import MMURequest::*;
import MMUIndication::*;
import MemServerIndication::*;
import MemServerRequest::*;

typedef enum {MemreadIndicationH2S, MemreadRequestS2H} TileNames deriving (Eq,Bits);
typedef enum {MMUIndicationH2S, MemServerIndicationH2S, MMURequestS2H, MemServerRequestS2H} FrameworkNames deriving (Eq,Bits);

module mkMemreadTile(Tile);

   MemreadIndicationProxy lMemreadIndicationProxy <- mkMemreadIndicationProxy(MemreadIndicationH2S);
   Memread lMemread <- mkMemread(lMemreadIndicationProxy.ifc);
   MemreadRequestWrapper lMemreadRequestWrapper <- mkMemreadRequestWrapper(MemreadRequestS2H, lMemread.request);

   Vector#(2,StdPortal) portal_vec;
   portal_vec[0] = lMemreadIndicationProxy.portalIfc;
   portal_vec[1] = lMemreadRequestWrapper.portalIfc;
   PhysMemSlave#(18,32) ctrl_mux <- mkSlaveMux(portal_vec);
   let interrupts <- mkInterruptMux(getInterruptVector(portal_vec));

   interface portals = ctrl_mux;
   interface interrupt = interrupts;
   interface reader = lMemread.dmaClient;
   interface writer = null_mem_write_client;
   interface pins = ?;

endmodule

module mkFramework(Framework#(numTiles,Empty,numMasters))
   provisos(Add#(a__, numTiles, 3)
	    ,Add#(c__, TLog#(d__), 6)
	    ,Mul#(d__, numMasters, numTiles)
	    ,Add#(1,numTiles,numInterrupts)
	    ,Add#(e__, TLog#(numInterrupts), 14)
	    ,Add#(b__, TLog#(f__), 6)
	    ,Mul#(f__, numMasters, TMul#(numTiles, 4))
	    );

   Vector#(numTiles, PhysMemConnector#(18,32)) portal_connectors <- replicateM(mkPhysMemConnector);
   Vector#(numTiles, MemreadConnector#(DataBusWidth)) tile_read_connectors <- replicateM(mkMemreadConnector);
   Vector#(numTiles, MemwriteConnector#(DataBusWidth)) tile_write_connectors <- replicateM(mkMemwriteConnector);
   Vector#(numTiles, MemReadClient#(DataBusWidth)) tile_read_clients = newVector;
   Vector#(numTiles, MemWriteClient#(DataBusWidth)) tile_write_clients = newVector;
   Vector#(numTiles, Wire#(Bool)) tile_interrupts <- replicateM(mkWire);

   Vector#(numTiles, TileSocket) tss = newVector;
   for(Integer i = 0; i < valueOf(numTiles); i=i+1) begin
      tile_read_clients[i] = tile_read_connectors[i].client;
      tile_write_clients[i] = tile_write_connectors[i].client;
      tss[i] = (interface TileSocket;
		   interface portals = portal_connectors[i].master;
		   interface WriteOnly interrupt;
		      method Action _write(Bool v) = tile_interrupts[i]._write(v);
		   endinterface
		   interface reader = tile_read_connectors[i].server;
		   interface writer = tile_write_connectors[i].server;
		   interface pins = ?;
		endinterface);
   end

   /////////////////////////////////////////////////////////////
   // framework internal portals

   MMUIndicationProxy lMMUIndicationProxy <- mkMMUIndicationProxy(MMUIndicationH2S);
   MemServerIndicationProxy lMemServerIndicationProxy <- mkMemServerIndicationProxy(MemServerIndicationH2S);

   MMU#(PhysAddrWidth) lMMU <- mkMMU(0,True, lMMUIndicationProxy.ifc);
   MemServer#(PhysAddrWidth,DataBusWidth,numMasters) lMemServer <- mkMemServerRW(lMemServerIndicationProxy.ifc, tile_read_clients, tile_write_clients, cons(lMMU,nil));

   MMURequestWrapper lMMURequestWrapper <- mkMMURequestWrapper(MMURequestS2H, lMMU.request);
   MemServerRequestWrapper lMemServerRequestWrapper <- mkMemServerRequestWrapper(MemServerRequestS2H, lMemServer.request);

   Vector#(4,StdPortal) framework_portals;
   framework_portals[0] = lMMUIndicationProxy.portalIfc;
   framework_portals[1] = lMemServerIndicationProxy.portalIfc;
   framework_portals[2] = lMMURequestWrapper.portalIfc;
   framework_portals[3] = lMemServerRequestWrapper.portalIfc;
   PhysMemSlave#(18,32) framework_ctrl_mux <- mkSlaveMux(framework_portals);
   let framework_intr <- mkInterruptMux(getInterruptVector(framework_portals));

   //
   /////////////////////////////////////////////////////////////

   PhysMemSlave#(32,32) ctrl_mux <- mkMemSlaveMux(cons(framework_ctrl_mux, map(getPhysMemConnectorSlave, portal_connectors)));
   Vector#(16, ReadOnly#(Bool)) interrupts = replicate(interface ReadOnly; method Bool _read(); return False; endmethod endinterface);
   interrupts[0] = framework_intr;
   for (Integer i = 1; i < valueOf(numInterrupts); i = i + 1)
      interrupts[i] = (interface ReadOnly;
			  method Bool _read();
			     return tile_interrupts[i-1]._read;
			  endmethod
		       endinterface);
   interface interrupt = interrupts;
   interface slave = ctrl_mux;
   interface masters = lMemServer.masters;
   interface pins = ?;
   interface sockets = tss;

endmodule

module mkConnectalTop(ConnectalTop#(PhysAddrWidth,DataBusWidth,Empty,1));

   Framework#(1,Empty,1) f <- mkFramework;
   Tile memreadTile <- mkMemreadTile;
   mkConnection(memreadTile, f.sockets[0]);

   interface interrupt = f.interrupt;
   interface slave = f.slave;
   interface masters = f.masters;
   interface pins = f.pins;

endmodule : mkConnectalTop

// Copyright (c) 2013 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import Vector::*;
import Connectable::*;

import Portal::*;
import CtrlMux::*;
import HostInterface::*;
import Tile::*;
import Memread::*;
import MMU::*;
import MemServer::*;
import MemTypes::*;

import MemreadRequest::*;
import MemreadIndication::*;
import MMURequest::*;
import MMUIndication::*;
import MemServerIndication::*;
import MemServerRequest::*;

typedef enum {MemreadIndicationH2S, MemreadRequestS2H} TileNames deriving (Eq,Bits);
typedef enum {MMUIndicationH2S, MemServerIndicationH2S, MMURequestS2H, MemServerRequestS2H} FrameworkNames deriving (Eq,Bits);

module mkMemreadTile(Tile);

   MemreadIndicationProxy lMemreadIndicationProxy <- mkMemreadIndicationProxy(MemreadIndicationH2S);
   Memread lMemread <- mkMemread(lMemreadIndicationProxy.ifc);
   MemreadRequestWrapper lMemreadRequestWrapper <- mkMemreadRequestWrapper(MemreadRequestS2H, lMemread.request);

   Vector#(2,StdPortal) portal_vec;
   portal_vec[0] = lMemreadIndicationProxy.portalIfc;
   portal_vec[1] = lMemreadRequestWrapper.portalIfc;
   PhysMemSlave#(18,32) ctrl_mux <- mkSlaveMux(portal_vec);
   let interrupts <- mkInterruptMux(getInterruptVector(portal_vec));

   interface portals = ctrl_mux;
   interface interrupt = interrupts;
   interface reader = lMemread.dmaClient;
   interface writer = null_mem_write_client;
   interface pins = ?;

endmodule

module mkFramework(Framework#(numTiles,Empty,numMasters))
   provisos(Add#(a__, numTiles, 3)
	    ,Add#(b__, TLog#(TAdd#(1, numTiles)), 14)
	    ,Add#(c__, TLog#(d__), 6)
	    ,Mul#(d__, numMasters, numTiles)
	    );

   Vector#(numTiles, PhysMemConnector#(18,32)) portal_connectors <- replicateM(mkPhysMemConnector);
   Vector#(numTiles, MemReadClient#(DataBusWidth)) tile_read_clients = newVector;
   Vector#(numTiles, MemWriteClient#(DataBusWidth)) tile_write_clients = newVector;
   Vector#(numTiles, Wire#(Bool)) tile_interrupts <- replicateM(mkWire);

   Vector#(numTiles, TileSocket) tss = newVector;
   for(Integer i = 0; i < valueOf(numTiles); i=i+1) begin
      tile_read_clients[i] = tile_read_connectors[i].client;
      tile_write_clients[i] = tile_write_connectors[i].client;
      tss[i] = (interface TileSocket;
		   interface portals = portal_connectors[i].master;
		   interface WriteOnly interrupt;
		      method Action _write(Bool v) = tile_interrupts[i]._write(v);
		   endinterface
		   interface reader = tile_read_connectors[i].server;
		   interface writer = tile_write_connectors[i].server;
		   interface pins = ?;
		endinterface);
   end

   /////////////////////////////////////////////////////////////
   // framework internal portals

   MMUIndicationProxy lMMUIndicationProxy <- mkMMUIndicationProxy(MMUIndicationH2S);
   MemServerIndicationProxy lMemServerIndicationProxy <- mkMemServerIndicationProxy(MemServerIndicationH2S);

   MMU#(PhysAddrWidth) lMMU <- mkMMU(0,True, lMMUIndicationProxy.ifc);
   MemServer#(PhysAddrWidth,DataBusWidth,numMasters) lMemServer <- mkMemServerRW(lMemServerIndicationProxy.ifc, tile_read_clients, tile_write_clients, cons(lMMU,nil));

   MMURequestWrapper lMMURequestWrapper <- mkMMURequestWrapper(MMURequestS2H, lMMU.request);
   MemServerRequestWrapper lMemServerRequestWrapper <- mkMemServerRequestWrapper(MemServerRequestS2H, lMemServer.request);

   Vector#(4,StdPortal) framework_portals;
   framework_portals[0] = lMMUIndicationProxy.portalIfc;
   framework_portals[1] = lMemServerIndicationProxy.portalIfc;
   framework_portals[2] = lMMURequestWrapper.portalIfc;
   framework_portals[3] = lMemServerRequestWrapper.portalIfc;
   PhysMemSlave#(18,32) framework_ctrl_mux <- mkSlaveMux(framework_portals);

   //
   /////////////////////////////////////////////////////////////

   Vector#(TAdd#(1,numTiles), PhysMemSlave#(18,32)) foo = cons(framework_ctrl_mux, map(getPhysMemConnectorSlave, portal_connectors));
   PhysMemSlave#(32,32) ctrl_mux <- mkMemSlaveMux(foo);

   interface interrupt = getInterruptVector(framework_portals);
   interface slave = ctrl_mux;
   interface masters = lMemServer.masters;
   interface pins = ?;
   interface sockets = tss;

endmodule

module mkConnectalTop(ConnectalTop#(PhysAddrWidth,DataBusWidth,Empty,1));

   Framework#(1,Empty,1) f <- mkFramework;
   Tile memreadTile <- mkMemreadTile;
   mkConnection(memreadTile, f.sockets[0]);

   interface interrupt = f.interrupt;
   interface slave = f.slave;
   interface masters = f.masters;
   interface pins = f.pins;

endmodule : mkConnectalTop


regenerated PCIEWRAPPER3

regenerated PCIEWRAPPER3

/*
   ../scripts/importbvi.py
   -I
   PcieWrap
   -P
   pcieWrap
   -n
   sys_reset
   -r
   sys_reset
   -n
   sys_clk
   -c
   sys_clk
   -n
   user_clk
   -c
   user_clk
   -n
   user_reset
   -r
   user_reset
   -n
   int_dclk_out
   -c
   int_dclk_out
   -n
   int_oobclk_out
   -c
   int_oobclk_out
   -n
   int_pipe_rxusrclk_out
   -c
   int_pipe_rxusrclk_out
   -n
   int_qplloutclk_out
   -c
   int_qplloutclk_out
   -n
   int_rxoutclk_out
   -c
   int_rxoutclk_out
   -n
   int_userclk1_out
   -n
   int_userclk2_out
   -c
   int_userclk1_out
   -c
   int_userclk2_out
   -n
   int_pclk_out_slave
   -c
   int_pclk_out_slave
   -n
   int_qplloutrefclk_out
   -c
   int_qplloutrefclk_out
   -f
   common
   -f
   int_qplllock
   -f
   int_pclk_sel
   -f
   pipe_userclk1
   -f
   pipe_userclk2
   -f
   cfg_mgmt_type1
   -f
   cfg_req_pm_transition
   -f
   pci_exp
   -f
   pipe
   -f
   user
   -o
   ../xilinx/PCIEWRAPPER3.bsv
   -p
   lanes
   ../../out/vc709/pcie3_7x_0/pcie3_7x_0_stub.v
*/

import Clocks::*;
import DefaultValue::*;
import XilinxCells::*;
import GetPut::*;
import AxiBits::*;

(* always_ready, always_enabled *)
interface PciewrapCfg#(numeric type lanes);
    method Action      interrupt_int(Bit#(4) v);
    method Action      interrupt_msix_address(Bit#(64) v);
    method Action      interrupt_msix_data(Bit#(32) v);
    method Bit#(2)     interrupt_msix_enable();
    method Bit#(1)     interrupt_msix_fail();
    method Action      interrupt_msix_int(Bit#(1) v);
    method Bit#(2)     interrupt_msix_mask();
    method Bit#(1)     interrupt_msix_sent();
    method Bit#(6)     interrupt_msix_vf_enable();
    method Bit#(6)     interrupt_msix_vf_mask();
    method Action      interrupt_pending(Bit#(2) v);
    method Bit#(1)     interrupt_sent();
endinterface
(* always_ready, always_enabled *)
interface PciewrapCommon#(numeric type lanes);
    method Action      commands_in(Bit#(26) v);
    method Bit#(17)     commands_out();
endinterface
(* always_ready, always_enabled *)
interface PciewrapInt_pclk_sel#(numeric type lanes);
    method Action      slave(Bit#(8) v);
endinterface
(* always_ready, always_enabled *)
interface PciewrapInt_qplllock#(numeric type lanes);
    method Bit#(2)     out();
endinterface
(* always_ready, always_enabled *)
interface PciewrapM_axis_cq#(numeric type lanes);
    method Bit#(256)     tdata();
    method Bit#(8)     tkeep();
    method Bit#(1)     tlast();
    method Action      tready(Bit#(1) v);
    method Bit#(85)     tuser();
    method Bit#(1)     tvalid();
endinterface
(* always_ready, always_enabled *)
interface PciewrapM_axis_rc#(numeric type lanes);
    method Bit#(256)     tdata();
    method Bit#(8)     tkeep();
    method Bit#(1)     tlast();
    method Action      tready(Bit#(1) v);
    method Bit#(75)     tuser();
    method Bit#(1)     tvalid();
endinterface
(* always_ready, always_enabled *)
interface PciewrapPci_exp#(numeric type lanes);
    method Action      rxn(Bit#(8) v);
    method Action      rxp(Bit#(8) v);
    method Bit#(8)     txn();
    method Bit#(8)     txp();
endinterface
(* always_ready, always_enabled *)
interface PciewrapPipe#(numeric type lanes);
    method Action      rx_0_sigs(Bit#(84) v);
    method Action      rx_1_sigs(Bit#(84) v);
    method Action      rx_2_sigs(Bit#(84) v);
    method Action      rx_3_sigs(Bit#(84) v);
    method Action      rx_4_sigs(Bit#(84) v);
    method Action      rx_5_sigs(Bit#(84) v);
    method Action      rx_6_sigs(Bit#(84) v);
    method Action      rx_7_sigs(Bit#(84) v);
    method Bit#(70)     tx_0_sigs();
    method Bit#(70)     tx_1_sigs();
    method Bit#(70)     tx_2_sigs();
    method Bit#(70)     tx_3_sigs();
    method Bit#(70)     tx_4_sigs();
    method Bit#(70)     tx_5_sigs();
    method Bit#(70)     tx_6_sigs();
    method Bit#(70)     tx_7_sigs();
endinterface
(* always_ready, always_enabled *)
interface PciewrapS_axis_cc#(numeric type lanes);
    method Action      tdata(Bit#(256) v);
    method Action      tkeep(Bit#(8) v);
    method Action      tlast(Bit#(1) v);
    method Bit#(4)     tready();
    method Action      tuser(Bit#(33) v);
    method Action      tvalid(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface PciewrapS_axis_rq#(numeric type lanes);
    method Action      tdata(Bit#(256) v);
    method Action      tkeep(Bit#(8) v);
    method Action      tlast(Bit#(1) v);
    method Bit#(4)     tready();
    method Action      tuser(Bit#(60) v);
    method Action      tvalid(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface PciewrapUser#(numeric type lanes);
    method Bit#(1)     app_rdy();
    method Bit#(1)     lnk_up();
endinterface
(* always_ready, always_enabled *)
interface PcieWrap#(numeric type lanes);
    interface PciewrapCfg#(lanes)     cfg;
    interface PciewrapCommon#(lanes)     common;
    interface Clock     int_dclk_out;
    interface Clock     int_oobclk_out;
    interface Clock     int_pclk_out_slave;
    interface PciewrapInt_pclk_sel#(lanes)     int_pclk_sel;
    interface Clock     int_pipe_rxusrclk_out;
    interface PciewrapInt_qplllock#(lanes)     int_qplllock;
    interface Clock     int_qplloutclk_out;
    interface Clock     int_qplloutrefclk_out;
    interface Clock     int_rxoutclk_out;
    interface Clock     int_userclk1_out;
    interface Clock     int_userclk2_out;
    interface PciewrapM_axis_cq#(lanes)     m_axis_cq;
    interface PciewrapM_axis_rc#(lanes)     m_axis_rc;
    interface PciewrapPci_exp#(lanes)     pci_exp;
    interface PciewrapPipe#(lanes)     pipe;
    interface PciewrapS_axis_cc#(lanes)     s_axis_cc;
    interface PciewrapS_axis_rq#(lanes)     s_axis_rq;
    interface PciewrapUser#(lanes)     user;
    interface Clock     user_clk;
    method Reset     user_reset();
endinterface
import "BVI" pcie3_7x_0 =
module mkPcieWrap#(Clock sys_clk, Reset sys_reset)(PcieWrap#(lanes));
    let lanes = valueOf(lanes);
    output_clock user_clk(user_clk);
    output_reset user_reset(user_reset);
    default_clock sys_clk(sys_clk) = sys_clk;
     /* from clock*/
    default_reset sys_reset(sys_reset) = sys_reset;
    interface PciewrapCfg     cfg;
        method interrupt_int(cfg_interrupt_int) enable((*inhigh*) EN_cfg_interrupt_int) clocked_by (user_clk) reset_by (user_reset);
        method interrupt_msix_address(cfg_interrupt_msix_address) enable((*inhigh*) EN_cfg_interrupt_msix_address) clocked_by (user_clk) reset_by (user_reset);
        method interrupt_msix_data(cfg_interrupt_msix_data) enable((*inhigh*) EN_cfg_interrupt_msix_data) clocked_by (user_clk) reset_by (user_reset);
        method cfg_interrupt_msix_enable interrupt_msix_enable() clocked_by (user_clk) reset_by (user_reset);
        method cfg_interrupt_msix_fail interrupt_msix_fail() clocked_by (user_clk) reset_by (user_reset);
        method interrupt_msix_int(cfg_interrupt_msix_int) enable((*inhigh*) EN_cfg_interrupt_msix_int) clocked_by (user_clk) reset_by (user_reset);
        method cfg_interrupt_msix_mask interrupt_msix_mask() clocked_by (user_clk) reset_by (user_reset);
        method cfg_interrupt_msix_sent interrupt_msix_sent() clocked_by (user_clk) reset_by (user_reset);
        method cfg_interrupt_msix_vf_enable interrupt_msix_vf_enable() clocked_by (user_clk) reset_by (user_reset);
        method cfg_interrupt_msix_vf_mask interrupt_msix_vf_mask() clocked_by (user_clk) reset_by (user_reset);
        method interrupt_pending(cfg_interrupt_pending) enable((*inhigh*) EN_cfg_interrupt_pending) clocked_by (user_clk) reset_by (user_reset);
        method cfg_interrupt_sent interrupt_sent() clocked_by (user_clk) reset_by (user_reset);
    endinterface
    interface PciewrapCommon     common;
        method commands_in(common_commands_in) enable((*inhigh*) EN_common_commands_in) clocked_by (user_clk) reset_by (user_reset);
        method common_commands_out commands_out();
    endinterface
    output_clock int_dclk_out(int_dclk_out);
    output_clock int_oobclk_out(int_oobclk_out);
    output_clock int_pclk_out_slave(int_pclk_out_slave);
    interface PciewrapInt_pclk_sel     int_pclk_sel;
        method slave(int_pclk_sel_slave) enable((*inhigh*) EN_int_pclk_sel_slave) clocked_by (user_clk) reset_by (user_reset);
    endinterface
    output_clock int_pipe_rxusrclk_out(int_pipe_rxusrclk_out);
    interface PciewrapInt_qplllock     int_qplllock;
        method int_qplllock_out out();
    endinterface
    output_clock int_qplloutclk_out(int_qplloutclk_out);
    output_clock int_qplloutrefclk_out(int_qplloutrefclk_out);
    output_clock int_rxoutclk_out(int_rxoutclk_out);
    output_clock int_userclk1_out(int_userclk1_out);
    output_clock int_userclk2_out(int_userclk2_out);
    interface PciewrapM_axis_cq     m_axis_cq;
        method m_axis_cq_tdata tdata() clocked_by (user_clk) reset_by (user_reset);
        method m_axis_cq_tkeep tkeep() clocked_by (user_clk) reset_by (user_reset);
        method m_axis_cq_tlast tlast() clocked_by (user_clk) reset_by (user_reset);
        method tready(m_axis_cq_tready) enable((*inhigh*) EN_m_axis_cq_tready) clocked_by (user_clk) reset_by (user_reset);
        method m_axis_cq_tuser tuser() clocked_by (user_clk) reset_by (user_reset);
        method m_axis_cq_tvalid tvalid() clocked_by (user_clk) reset_by (user_reset);
    endinterface
    interface PciewrapM_axis_rc     m_axis_rc;
        method m_axis_rc_tdata tdata() clocked_by (user_clk) reset_by (user_reset);
        method m_axis_rc_tkeep tkeep() clocked_by (user_clk) reset_by (user_reset);
        method m_axis_rc_tlast tlast() clocked_by (user_clk) reset_by (user_reset);
        method tready(m_axis_rc_tready) enable((*inhigh*) EN_m_axis_rc_tready) clocked_by (user_clk) reset_by (user_reset);
        method m_axis_rc_tuser tuser() clocked_by (user_clk) reset_by (user_reset);
        method m_axis_rc_tvalid tvalid() clocked_by (user_clk) reset_by (user_reset);
    endinterface
    interface PciewrapPci_exp     pci_exp;
        method rxn(pci_exp_rxn) enable((*inhigh*) EN_pci_exp_rxn)  clocked_by (sys_clk) reset_by (sys_reset);
        method rxp(pci_exp_rxp) enable((*inhigh*) EN_pci_exp_rxp)  clocked_by (sys_clk) reset_by (sys_reset);
        method pci_exp_txn txn() clocked_by (sys_clk) reset_by (sys_reset);
        method pci_exp_txp txp() clocked_by (sys_clk) reset_by (sys_reset);
    endinterface
    interface PciewrapPipe     pipe;
        method rx_0_sigs(pipe_rx_0_sigs) enable((*inhigh*) EN_pipe_rx_0_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_1_sigs(pipe_rx_1_sigs) enable((*inhigh*) EN_pipe_rx_1_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_2_sigs(pipe_rx_2_sigs) enable((*inhigh*) EN_pipe_rx_2_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_3_sigs(pipe_rx_3_sigs) enable((*inhigh*) EN_pipe_rx_3_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_4_sigs(pipe_rx_4_sigs) enable((*inhigh*) EN_pipe_rx_4_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_5_sigs(pipe_rx_5_sigs) enable((*inhigh*) EN_pipe_rx_5_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_6_sigs(pipe_rx_6_sigs) enable((*inhigh*) EN_pipe_rx_6_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_7_sigs(pipe_rx_7_sigs) enable((*inhigh*) EN_pipe_rx_7_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method pipe_tx_0_sigs tx_0_sigs();
        method pipe_tx_1_sigs tx_1_sigs();
        method pipe_tx_2_sigs tx_2_sigs();
        method pipe_tx_3_sigs tx_3_sigs();
        method pipe_tx_4_sigs tx_4_sigs();
        method pipe_tx_5_sigs tx_5_sigs();
        method pipe_tx_6_sigs tx_6_sigs();
        method pipe_tx_7_sigs tx_7_sigs();
    endinterface
    interface PciewrapS_axis_cc     s_axis_cc;
        method tdata(s_axis_cc_tdata) enable((*inhigh*) EN_s_axis_cc_tdata) clocked_by (user_clk) reset_by (user_reset);
        method tkeep(s_axis_cc_tkeep) enable((*inhigh*) EN_s_axis_cc_tkeep) clocked_by (user_clk) reset_by (user_reset);
        method tlast(s_axis_cc_tlast) enable((*inhigh*) EN_s_axis_cc_tlast) clocked_by (user_clk) reset_by (user_reset);
        method s_axis_cc_tready tready() clocked_by (user_clk) reset_by (user_reset);
        method tuser(s_axis_cc_tuser) enable((*inhigh*) EN_s_axis_cc_tuser) clocked_by (user_clk) reset_by (user_reset);
        method tvalid(s_axis_cc_tvalid) enable((*inhigh*) EN_s_axis_cc_tvalid) clocked_by (user_clk) reset_by (user_reset);
    endinterface
    interface PciewrapS_axis_rq     s_axis_rq;
        method tdata(s_axis_rq_tdata) enable((*inhigh*) EN_s_axis_rq_tdata) clocked_by (user_clk) reset_by (user_reset);
        method tkeep(s_axis_rq_tkeep) enable((*inhigh*) EN_s_axis_rq_tkeep) clocked_by (user_clk) reset_by (user_reset);
        method tlast(s_axis_rq_tlast) enable((*inhigh*) EN_s_axis_rq_tlast) clocked_by (user_clk) reset_by (user_reset);
        method s_axis_rq_tready tready() clocked_by (user_clk) reset_by (user_reset);
        method tuser(s_axis_rq_tuser) enable((*inhigh*) EN_s_axis_rq_tuser) clocked_by (user_clk) reset_by (user_reset);
        method tvalid(s_axis_rq_tvalid) enable((*inhigh*) EN_s_axis_rq_tvalid) clocked_by (user_clk) reset_by (user_reset);
    endinterface
    interface PciewrapUser     user;
        method user_app_rdy app_rdy() clocked_by (user_clk) reset_by (user_reset);
        method user_lnk_up lnk_up() clocked_by (user_clk) reset_by (user_reset);
    endinterface

    schedule (cfg.interrupt_int, cfg.interrupt_msix_address, cfg.interrupt_msix_data, cfg.interrupt_msix_enable, cfg.interrupt_msix_fail, cfg.interrupt_msix_int, cfg.interrupt_msix_mask, cfg.interrupt_msix_sent, cfg.interrupt_msix_vf_enable, cfg.interrupt_msix_vf_mask, cfg.interrupt_pending, cfg.interrupt_sent, common.commands_in, common.commands_out, int_pclk_sel.slave, int_qplllock.out, m_axis_cq.tdata, m_axis_cq.tkeep, m_axis_cq.tlast, m_axis_cq.tready, m_axis_cq.tuser, m_axis_cq.tvalid, m_axis_rc.tdata, m_axis_rc.tkeep, m_axis_rc.tlast, m_axis_rc.tready, m_axis_rc.tuser, m_axis_rc.tvalid, pci_exp.rxn, pci_exp.rxp, pci_exp.txn, pci_exp.txp, pipe.rx_0_sigs, pipe.rx_1_sigs, pipe.rx_2_sigs, pipe.rx_3_sigs, pipe.rx_4_sigs, pipe.rx_5_sigs, pipe.rx_6_sigs, pipe.rx_7_sigs, pipe.tx_0_sigs, pipe.tx_1_sigs, pipe.tx_2_sigs, pipe.tx_3_sigs, pipe.tx_4_sigs, pipe.tx_5_sigs, pipe.tx_6_sigs, pipe.tx_7_sigs, s_axis_cc.tdata, s_axis_cc.tkeep, s_axis_cc.tlast, s_axis_cc.tready, s_axis_cc.tuser, s_axis_cc.tvalid, s_axis_rq.tdata, s_axis_rq.tkeep, s_axis_rq.tlast, s_axis_rq.tready, s_axis_rq.tuser, s_axis_rq.tvalid, user.app_rdy, user.lnk_up) CF (cfg.interrupt_int, cfg.interrupt_msix_address, cfg.interrupt_msix_data, cfg.interrupt_msix_enable, cfg.interrupt_msix_fail, cfg.interrupt_msix_int, cfg.interrupt_msix_mask, cfg.interrupt_msix_sent, cfg.interrupt_msix_vf_enable, cfg.interrupt_msix_vf_mask, cfg.interrupt_pending, cfg.interrupt_sent, common.commands_in, common.commands_out, int_pclk_sel.slave, int_qplllock.out, m_axis_cq.tdata, m_axis_cq.tkeep, m_axis_cq.tlast, m_axis_cq.tready, m_axis_cq.tuser, m_axis_cq.tvalid, m_axis_rc.tdata, m_axis_rc.tkeep, m_axis_rc.tlast, m_axis_rc.tready, m_axis_rc.tuser, m_axis_rc.tvalid, pci_exp.rxn, pci_exp.rxp, pci_exp.txn, pci_exp.txp, pipe.rx_0_sigs, pipe.rx_1_sigs, pipe.rx_2_sigs, pipe.rx_3_sigs, pipe.rx_4_sigs, pipe.rx_5_sigs, pipe.rx_6_sigs, pipe.rx_7_sigs, pipe.tx_0_sigs, pipe.tx_1_sigs, pipe.tx_2_sigs, pipe.tx_3_sigs, pipe.tx_4_sigs, pipe.tx_5_sigs, pipe.tx_6_sigs, pipe.tx_7_sigs, s_axis_cc.tdata, s_axis_cc.tkeep, s_axis_cc.tlast, s_axis_cc.tready, s_axis_cc.tuser, s_axis_cc.tvalid, s_axis_rq.tdata, s_axis_rq.tkeep, s_axis_rq.tlast, s_axis_rq.tready, s_axis_rq.tuser, s_axis_rq.tvalid, user.app_rdy, user.lnk_up);
endmodule

/*
   ../scripts/importbvi.py
   -I
   PcieWrap
   -P
   pcieWrap
   -n
   sys_reset
   -r
   sys_reset
   -n
   sys_clk
   -c
   sys_clk
   -n
   user_clk
   -c
   user_clk
   -n
   user_reset
   -r
   user_reset
   -n
   int_dclk_out
   -c
   int_dclk_out
   -n
   int_oobclk_out
   -c
   int_oobclk_out
   -n
   int_pipe_rxusrclk_out
   -c
   int_pipe_rxusrclk_out
   -n
   int_qplloutclk_out
   -c
   int_qplloutclk_out
   -n
   int_rxoutclk_out
   -c
   int_rxoutclk_out
   -n
   int_userclk1_out
   -n
   int_userclk2_out
   -c
   int_userclk1_out
   -c
   int_userclk2_out
   -n
   int_pclk_out_slave
   -c
   int_pclk_out_slave
   -n
   int_qplloutrefclk_out
   -c
   int_qplloutrefclk_out
   -f
   common
   -f
   int_qplllock
   -f
   int_pclk_sel
   -f
   pipe_userclk1
   -f
   pipe_userclk2
   -f
   cfg_mgmt_type1
   -f
   cfg_req_pm_transition
   -f
   pci_exp
   -f
   pipe
   -f
   user
   -o
   ../xilinx/PCIEWRAPPER3.bsv
   -p
   lanes
   ../../out/nfsume/pcie3_7x_0/pcie3_7x_0_stub.v
*/

import Clocks::*;
import DefaultValue::*;
import XilinxCells::*;
import GetPut::*;
import AxiBits::*;

(* always_ready, always_enabled *)
interface PciewrapCfg#(numeric type lanes);
    method Action      interrupt_int(Bit#(4) v);
    method Action      interrupt_msix_address(Bit#(64) v);
    method Action      interrupt_msix_data(Bit#(32) v);
    method Bit#(2)     interrupt_msix_enable();
    method Bit#(1)     interrupt_msix_fail();
    method Action      interrupt_msix_int(Bit#(1) v);
    method Bit#(2)     interrupt_msix_mask();
    method Bit#(1)     interrupt_msix_sent();
    method Bit#(6)     interrupt_msix_vf_enable();
    method Bit#(6)     interrupt_msix_vf_mask();
    method Action      interrupt_pending(Bit#(2) v);
    method Bit#(1)     interrupt_sent();
endinterface
(* always_ready, always_enabled *)
interface PciewrapCommon#(numeric type lanes);
    method Action      commands_in(Bit#(26) v);
    method Bit#(17)     commands_out();
endinterface
(* always_ready, always_enabled *)
interface PciewrapInt_pclk_sel#(numeric type lanes);
    method Action      slave(Bit#(8) v);
endinterface
(* always_ready, always_enabled *)
interface PciewrapInt_qplllock#(numeric type lanes);
    method Bit#(2)     out();
endinterface
(* always_ready, always_enabled *)
interface PciewrapM_axis_cq#(numeric type lanes);
    method Bit#(256)     tdata();
    method Bit#(8)     tkeep();
    method Bit#(1)     tlast();
    method Action      tready(Bit#(22) v);
    method Bit#(85)     tuser();
    method Bit#(1)     tvalid();
endinterface
(* always_ready, always_enabled *)
interface PciewrapM_axis_rc#(numeric type lanes);
    method Bit#(256)     tdata();
    method Bit#(8)     tkeep();
    method Bit#(1)     tlast();
    method Action      tready(Bit#(22) v);
    method Bit#(75)     tuser();
    method Bit#(1)     tvalid();
endinterface
(* always_ready, always_enabled *)
interface PciewrapPci_exp#(numeric type lanes);
    method Action      rxn(Bit#(8) v);
    method Action      rxp(Bit#(8) v);
    method Bit#(8)     txn();
    method Bit#(8)     txp();
endinterface
(* always_ready, always_enabled *)
interface PciewrapPipe#(numeric type lanes);
    method Action      rx_0_sigs(Bit#(84) v);
    method Action      rx_1_sigs(Bit#(84) v);
    method Action      rx_2_sigs(Bit#(84) v);
    method Action      rx_3_sigs(Bit#(84) v);
    method Action      rx_4_sigs(Bit#(84) v);
    method Action      rx_5_sigs(Bit#(84) v);
    method Action      rx_6_sigs(Bit#(84) v);
    method Action      rx_7_sigs(Bit#(84) v);
    method Bit#(70)     tx_0_sigs();
    method Bit#(70)     tx_1_sigs();
    method Bit#(70)     tx_2_sigs();
    method Bit#(70)     tx_3_sigs();
    method Bit#(70)     tx_4_sigs();
    method Bit#(70)     tx_5_sigs();
    method Bit#(70)     tx_6_sigs();
    method Bit#(70)     tx_7_sigs();
endinterface
(* always_ready, always_enabled *)
interface PciewrapS_axis_cc#(numeric type lanes);
    method Action      tdata(Bit#(256) v);
    method Action      tkeep(Bit#(8) v);
    method Action      tlast(Bit#(1) v);
    method Bit#(4)     tready();
    method Action      tuser(Bit#(33) v);
    method Action      tvalid(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface PciewrapS_axis_rq#(numeric type lanes);
    method Action      tdata(Bit#(256) v);
    method Action      tkeep(Bit#(8) v);
    method Action      tlast(Bit#(1) v);
    method Bit#(4)     tready();
    method Action      tuser(Bit#(60) v);
    method Action      tvalid(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface PciewrapUser#(numeric type lanes);
    method Bit#(1)     app_rdy();
    method Bit#(1)     lnk_up();
endinterface
(* always_ready, always_enabled *)
interface PcieWrap#(numeric type lanes);
    interface PciewrapCfg#(lanes)     cfg;
    interface PciewrapCommon#(lanes)     common;
    interface Clock     int_dclk_out;
    interface Clock     int_oobclk_out;
    interface Clock     int_pclk_out_slave;
    interface PciewrapInt_pclk_sel#(lanes)     int_pclk_sel;
    interface Clock     int_pipe_rxusrclk_out;
    interface PciewrapInt_qplllock#(lanes)     int_qplllock;
    interface Clock     int_qplloutclk_out;
    interface Clock     int_qplloutrefclk_out;
    interface Clock     int_rxoutclk_out;
    interface Clock     int_userclk1_out;
    interface Clock     int_userclk2_out;
    interface PciewrapM_axis_cq#(lanes)     m_axis_cq;
    interface PciewrapM_axis_rc#(lanes)     m_axis_rc;
    interface PciewrapPci_exp#(lanes)     pci_exp;
    interface PciewrapPipe#(lanes)     pipe;
    interface PciewrapS_axis_cc#(lanes)     s_axis_cc;
    interface PciewrapS_axis_rq#(lanes)     s_axis_rq;
    interface PciewrapUser#(lanes)     user;
    interface Clock     user_clk;
    method Reset     user_reset();
endinterface
import "BVI" pcie3_7x_0 =
module mkPcieWrap#(Clock sys_clk, Reset sys_reset)(PcieWrap#(lanes));
    let lanes = valueOf(lanes);
    output_clock user_clk(user_clk);
    output_reset user_reset(user_reset);
    default_clock sys_clk(sys_clk) = sys_clk;
     /* from clock*/
    default_reset sys_reset(sys_reset) = sys_reset;
    interface PciewrapCfg     cfg;
        method interrupt_int(cfg_interrupt_int) enable((*inhigh*) EN_cfg_interrupt_int) clocked_by (user_clk) reset_by (no_reset);
        method interrupt_msix_address(cfg_interrupt_msix_address) enable((*inhigh*) EN_cfg_interrupt_msix_address) clocked_by (user_clk) reset_by (no_reset);
        method interrupt_msix_data(cfg_interrupt_msix_data) enable((*inhigh*) EN_cfg_interrupt_msix_data) clocked_by (user_clk) reset_by (no_reset);
        method cfg_interrupt_msix_enable interrupt_msix_enable() clocked_by (user_clk) reset_by (no_reset);
        method cfg_interrupt_msix_fail interrupt_msix_fail() clocked_by (user_clk) reset_by (no_reset);
        method interrupt_msix_int(cfg_interrupt_msix_int) enable((*inhigh*) EN_cfg_interrupt_msix_int) clocked_by (user_clk) reset_by (no_reset);
        method cfg_interrupt_msix_mask interrupt_msix_mask() clocked_by (user_clk) reset_by (no_reset);
        method cfg_interrupt_msix_sent interrupt_msix_sent() clocked_by (user_clk) reset_by (no_reset);
        method cfg_interrupt_msix_vf_enable interrupt_msix_vf_enable() clocked_by (user_clk) reset_by (no_reset);
        method cfg_interrupt_msix_vf_mask interrupt_msix_vf_mask() clocked_by (user_clk) reset_by (no_reset);
        method interrupt_pending(cfg_interrupt_pending) enable((*inhigh*) EN_cfg_interrupt_pending) clocked_by (user_clk) reset_by (no_reset);
        method cfg_interrupt_sent interrupt_sent() clocked_by (user_clk) reset_by (no_reset);
    endinterface
    interface PciewrapCommon     common;
        method commands_in(common_commands_in) enable((*inhigh*) EN_common_commands_in) clocked_by (user_clk) reset_by (no_reset);
        method common_commands_out commands_out();
    endinterface
    output_clock int_dclk_out(int_dclk_out);
    output_clock int_oobclk_out(int_oobclk_out);
    output_clock int_pclk_out_slave(int_pclk_out_slave);
    interface PciewrapInt_pclk_sel     int_pclk_sel;
        method slave(int_pclk_sel_slave) enable((*inhigh*) EN_int_pclk_sel_slave) clocked_by (user_clk) reset_by (no_reset);
    endinterface
    output_clock int_pipe_rxusrclk_out(int_pipe_rxusrclk_out);
    interface PciewrapInt_qplllock     int_qplllock;
        method int_qplllock_out out();
    endinterface
    output_clock int_qplloutclk_out(int_qplloutclk_out);
    output_clock int_qplloutrefclk_out(int_qplloutrefclk_out);
    output_clock int_rxoutclk_out(int_rxoutclk_out);
    output_clock int_userclk1_out(int_userclk1_out);
    output_clock int_userclk2_out(int_userclk2_out);
    interface PciewrapM_axis_cq     m_axis_cq;
        method m_axis_cq_tdata tdata() clocked_by (user_clk) reset_by (no_reset);
        method m_axis_cq_tkeep tkeep() clocked_by (user_clk) reset_by (no_reset);
        method m_axis_cq_tlast tlast() clocked_by (user_clk) reset_by (no_reset);
        method tready(m_axis_cq_tready) enable((*inhigh*) EN_m_axis_cq_tready) clocked_by (user_clk) reset_by (no_reset);
        method m_axis_cq_tuser tuser() clocked_by (user_clk) reset_by (no_reset);
        method m_axis_cq_tvalid tvalid() clocked_by (user_clk) reset_by (no_reset);
    endinterface
    interface PciewrapM_axis_rc     m_axis_rc;
        method m_axis_rc_tdata tdata() clocked_by (user_clk) reset_by (no_reset);
        method m_axis_rc_tkeep tkeep() clocked_by (user_clk) reset_by (no_reset);
        method m_axis_rc_tlast tlast() clocked_by (user_clk) reset_by (no_reset);
        method tready(m_axis_rc_tready) enable((*inhigh*) EN_m_axis_rc_tready) clocked_by (user_clk) reset_by (no_reset);
        method m_axis_rc_tuser tuser() clocked_by (user_clk) reset_by (no_reset);
        method m_axis_rc_tvalid tvalid() clocked_by (user_clk) reset_by (no_reset);
    endinterface
    interface PciewrapPci_exp     pci_exp;
        method rxn(pci_exp_rxn) enable((*inhigh*) EN_pci_exp_rxn)  clocked_by (sys_clk) reset_by (sys_reset);
        method rxp(pci_exp_rxp) enable((*inhigh*) EN_pci_exp_rxp)  clocked_by (sys_clk) reset_by (sys_reset);
        method pci_exp_txn txn() clocked_by (sys_clk) reset_by (sys_reset);
        method pci_exp_txp txp() clocked_by (sys_clk) reset_by (sys_reset);
    endinterface
    interface PciewrapPipe     pipe;
        method rx_0_sigs(pipe_rx_0_sigs) enable((*inhigh*) EN_pipe_rx_0_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_1_sigs(pipe_rx_1_sigs) enable((*inhigh*) EN_pipe_rx_1_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_2_sigs(pipe_rx_2_sigs) enable((*inhigh*) EN_pipe_rx_2_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_3_sigs(pipe_rx_3_sigs) enable((*inhigh*) EN_pipe_rx_3_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_4_sigs(pipe_rx_4_sigs) enable((*inhigh*) EN_pipe_rx_4_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_5_sigs(pipe_rx_5_sigs) enable((*inhigh*) EN_pipe_rx_5_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_6_sigs(pipe_rx_6_sigs) enable((*inhigh*) EN_pipe_rx_6_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method rx_7_sigs(pipe_rx_7_sigs) enable((*inhigh*) EN_pipe_rx_7_sigs)  clocked_by (sys_clk) reset_by (sys_reset);
        method pipe_tx_0_sigs tx_0_sigs();
        method pipe_tx_1_sigs tx_1_sigs();
        method pipe_tx_2_sigs tx_2_sigs();
        method pipe_tx_3_sigs tx_3_sigs();
        method pipe_tx_4_sigs tx_4_sigs();
        method pipe_tx_5_sigs tx_5_sigs();
        method pipe_tx_6_sigs tx_6_sigs();
        method pipe_tx_7_sigs tx_7_sigs();
    endinterface
    interface PciewrapS_axis_cc     s_axis_cc;
        method tdata(s_axis_cc_tdata) enable((*inhigh*) EN_s_axis_cc_tdata) clocked_by (user_clk) reset_by (no_reset);
        method tkeep(s_axis_cc_tkeep) enable((*inhigh*) EN_s_axis_cc_tkeep) clocked_by (user_clk) reset_by (no_reset);
        method tlast(s_axis_cc_tlast) enable((*inhigh*) EN_s_axis_cc_tlast) clocked_by (user_clk) reset_by (no_reset);
        method s_axis_cc_tready tready() clocked_by (user_clk) reset_by (no_reset);
        method tuser(s_axis_cc_tuser) enable((*inhigh*) EN_s_axis_cc_tuser) clocked_by (user_clk) reset_by (no_reset);
        method tvalid(s_axis_cc_tvalid) enable((*inhigh*) EN_s_axis_cc_tvalid) clocked_by (user_clk) reset_by (no_reset);
    endinterface
    interface PciewrapS_axis_rq     s_axis_rq;
        method tdata(s_axis_rq_tdata) enable((*inhigh*) EN_s_axis_rq_tdata) clocked_by (user_clk) reset_by (no_reset);
        method tkeep(s_axis_rq_tkeep) enable((*inhigh*) EN_s_axis_rq_tkeep) clocked_by (user_clk) reset_by (no_reset);
        method tlast(s_axis_rq_tlast) enable((*inhigh*) EN_s_axis_rq_tlast) clocked_by (user_clk) reset_by (no_reset);
        method s_axis_rq_tready tready() clocked_by (user_clk) reset_by (no_reset);
        method tuser(s_axis_rq_tuser) enable((*inhigh*) EN_s_axis_rq_tuser) clocked_by (user_clk) reset_by (no_reset);
        method tvalid(s_axis_rq_tvalid) enable((*inhigh*) EN_s_axis_rq_tvalid) clocked_by (user_clk) reset_by (no_reset);
    endinterface
    interface PciewrapUser     user;
        method user_app_rdy app_rdy() clocked_by (user_clk) reset_by (no_reset);
        method user_lnk_up lnk_up() clocked_by (user_clk) reset_by (no_reset);
    endinterface

    schedule (cfg.interrupt_int, cfg.interrupt_msix_address, cfg.interrupt_msix_data, cfg.interrupt_msix_enable, cfg.interrupt_msix_fail, cfg.interrupt_msix_int, cfg.interrupt_msix_mask, cfg.interrupt_msix_sent, cfg.interrupt_msix_vf_enable, cfg.interrupt_msix_vf_mask, cfg.interrupt_pending, cfg.interrupt_sent, common.commands_in, common.commands_out, int_pclk_sel.slave, int_qplllock.out, m_axis_cq.tdata, m_axis_cq.tkeep, m_axis_cq.tlast, m_axis_cq.tready, m_axis_cq.tuser, m_axis_cq.tvalid, m_axis_rc.tdata, m_axis_rc.tkeep, m_axis_rc.tlast, m_axis_rc.tready, m_axis_rc.tuser, m_axis_rc.tvalid, pci_exp.rxn, pci_exp.rxp, pci_exp.txn, pci_exp.txp, pipe.rx_0_sigs, pipe.rx_1_sigs, pipe.rx_2_sigs, pipe.rx_3_sigs, pipe.rx_4_sigs, pipe.rx_5_sigs, pipe.rx_6_sigs, pipe.rx_7_sigs, pipe.tx_0_sigs, pipe.tx_1_sigs, pipe.tx_2_sigs, pipe.tx_3_sigs, pipe.tx_4_sigs, pipe.tx_5_sigs, pipe.tx_6_sigs, pipe.tx_7_sigs, s_axis_cc.tdata, s_axis_cc.tkeep, s_axis_cc.tlast, s_axis_cc.tready, s_axis_cc.tuser, s_axis_cc.tvalid, s_axis_rq.tdata, s_axis_rq.tkeep, s_axis_rq.tlast, s_axis_rq.tready, s_axis_rq.tuser, s_axis_rq.tvalid, user.app_rdy, user.lnk_up) CF (cfg.interrupt_int, cfg.interrupt_msix_address, cfg.interrupt_msix_data, cfg.interrupt_msix_enable, cfg.interrupt_msix_fail, cfg.interrupt_msix_int, cfg.interrupt_msix_mask, cfg.interrupt_msix_sent, cfg.interrupt_msix_vf_enable, cfg.interrupt_msix_vf_mask, cfg.interrupt_pending, cfg.interrupt_sent, common.commands_in, common.commands_out, int_pclk_sel.slave, int_qplllock.out, m_axis_cq.tdata, m_axis_cq.tkeep, m_axis_cq.tlast, m_axis_cq.tready, m_axis_cq.tuser, m_axis_cq.tvalid, m_axis_rc.tdata, m_axis_rc.tkeep, m_axis_rc.tlast, m_axis_rc.tready, m_axis_rc.tuser, m_axis_rc.tvalid, pci_exp.rxn, pci_exp.rxp, pci_exp.txn, pci_exp.txp, pipe.rx_0_sigs, pipe.rx_1_sigs, pipe.rx_2_sigs, pipe.rx_3_sigs, pipe.rx_4_sigs, pipe.rx_5_sigs, pipe.rx_6_sigs, pipe.rx_7_sigs, pipe.tx_0_sigs, pipe.tx_1_sigs, pipe.tx_2_sigs, pipe.tx_3_sigs, pipe.tx_4_sigs, pipe.tx_5_sigs, pipe.tx_6_sigs, pipe.tx_7_sigs, s_axis_cc.tdata, s_axis_cc.tkeep, s_axis_cc.tlast, s_axis_cc.tready, s_axis_cc.tuser, s_axis_cc.tvalid, s_axis_rq.tdata, s_axis_rq.tkeep, s_axis_rq.tlast, s_axis_rq.tready, s_axis_rq.tuser, s_axis_rq.tvalid, user.app_rdy, user.lnk_up);
endmodule


added mkSimpleMemServer, which also creates the MMU

// Copyright (c) 2013 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

// BSV Libraries
import FIFO::*;
import Vector::*;
import List::*;
import GetPut::*;
import ClientServer::*;
import Assert::*;
import StmtFSM::*;

// CONNECTAL Libraries
import HostInterface::*;
import MemTypes::*;
import ConnectalMemory::*;
import MMU::*;
import MemServerInternal::*;

function Put#(t) null_put();
   return (interface Put;
              method Action put(t x) if (False);
                 noAction;
              endmethod
           endinterface);
endfunction

function Get#(t) null_get();
   return (interface Get;
              method ActionValue#(t) get() if (False);
                 return ?;
              endmethod
           endinterface);
endfunction

function  PhysMemWriteClient#(addrWidth, busWidth) null_phys_mem_write_client();
   return (interface PhysMemWriteClient;
              interface Get writeReq = null_get;
              interface Get writeData = null_get;
              interface Put writeDone = null_put;
           endinterface);
endfunction

function  PhysMemReadClient#(addrWidth, busWidth) null_phys_mem_read_client();
   return (interface PhysMemReadClient;
              interface Get readReq = null_get;
              interface Put readData = null_put;
           endinterface);
endfunction

function  MemWriteClient#(busWidth) null_mem_write_client();
   return (interface MemWriteClient;
              interface Get writeReq = null_get;
              interface Get writeData = null_get;
              interface Put writeDone = null_put;
           endinterface);
endfunction

function  MemReadClient#(busWidth) null_mem_read_client();
   return (interface MemReadClient;
              interface Get readReq = null_get;
              interface Put readData = null_put;
           endinterface);
endfunction

interface MemServer#(numeric type addrWidth, numeric type dataWidth, numeric type nMasters);
   interface MemServerRequest request;
   interface Vector#(nMasters,PhysMemMaster#(addrWidth, dataWidth)) masters;
endinterface

typedef struct {
   DmaErrorType errorType;
   Bit#(32) pref;
   } DmaError deriving (Bits);

module mkMemServerRW#(MemServerIndication indication,
		      Vector#(numReadClients, MemReadClient#(dataWidth)) readClients,
		      Vector#(numWriteClients, MemWriteClient#(dataWidth)) writeClients,
		      Vector#(numMMUs,MMU#(PhysAddrWidth)) mmus)
   (MemServer#(PhysAddrWidth, dataWidth, nMasters))

   provisos (Add#(1,a__,dataWidth),
	     Mul#(TDiv#(dataWidth, 8), 8, dataWidth),
	     Mul#(nwc, nMasters, numWriteClients),
	     Mul#(nrc, nMasters, numReadClients),
	     Add#(b__, TLog#(nrc), 6),
	     Add#(c__, TLog#(nwc), 6),
	     Add#(TLog#(TDiv#(dataWidth, 8)), d__, BurstLenSize)
	     );

   MemServer#(PhysAddrWidth,dataWidth,nMasters) reader <- mkMemServerR(indication,  readClients, mmus);
   MemServer#(PhysAddrWidth,dataWidth,nMasters) writer <- mkMemServerW(indication, writeClients, mmus);

   function PhysMemMaster#(PhysAddrWidth,dataWidth) mkm(Integer i) = (interface PhysMemMaster#(PhysAddrWidth,dataWidth);
								 interface PhysMemReadClient read_client = reader.masters[i].read_client;
								 interface PhysMemWriteClient write_client = writer.masters[i].write_client;
							      endinterface);

   interface MemServerRequest request;
      method Action stateDbg(ChannelType rc);
	 if (rc == Read)
	    reader.request.stateDbg(rc);
	 else
	    writer.request.stateDbg(rc);
      endmethod
      method Action memoryTraffic(ChannelType rc);
	 if (rc == Read)
	    reader.request.memoryTraffic(rc);
	 else
	    writer.request.memoryTraffic(rc);
      endmethod
      method Action addrTrans(Bit#(32) pointer, Bit#(32) offset);
	 writer.request.addrTrans(pointer,offset);
      endmethod
   endinterface
   interface masters = map(mkm,genVector);
endmodule

module mkMemServerR#(MemServerIndication indication,
		       Vector#(numReadClients, MemReadClient#(dataWidth)) readClients,
		       Vector#(numMMUs,MMU#(addrWidth)) mmus)
   (MemServer#(addrWidth, dataWidth, nMasters))

   provisos (Add#(1,a__,dataWidth),
	     Mul#(TDiv#(dataWidth, 8), 8, dataWidth),
	     Mul#(nrc, nMasters, numReadClients),
	     Add#(b__, TLog#(nrc), 6),
	     Add#(TLog#(TDiv#(dataWidth, 8)), c__, BurstLenSize)
	     ,Add#(d__, addrWidth, 64)
	     ,Add#(e__, 12, addrWidth)
	     ,Add#(1, e__, f__)
	     );

   FIFO#(Bit#(32))   addrReqFifo <- mkFIFO;
   Reg#(Bit#(8)) dbgPtr <- mkReg(0);
   Reg#(Bit#(8)) trafficPtr <- mkReg(0);
   Reg#(Bit#(64)) trafficAccum <- mkReg(0);

   function a selectClient(Vector#(n, a) in, Integer r, Integer i, Integer j); return in[j * r + i]; endfunction
   function Vector#(nrc, a) selectClients(Vector#(numReadClients, a) vec, Integer m);
      return genWith(selectClient(vec, valueOf(nMasters), m));
   endfunction
   Vector#(nMasters,Vector#(nrc, MemReadClient#(dataWidth))) client_bins = genWith(selectClients(readClients));

   module foo#(Integer i) (MMUAddrServer#(addrWidth,nMasters));
      let rv <- mkMMUAddrServer(mmus[i].addr[0]);
      return rv;
   endmodule
   Vector#(numMMUs,MMUAddrServer#(addrWidth,nMasters)) mmu_servers <- mapM(foo,genVector);

   Vector#(nMasters,MemReadInternal#(addrWidth,dataWidth,MemServerTags)) readers;
   for(Integer i = 0; i < valueOf(nMasters); i = i+1) begin
      Vector#(numMMUs,Server#(ReqTup,Bit#(addrWidth))) ss;
      for(Integer j = 0; j < valueOf(numMMUs); j=j+1)
	 ss[j] = mmu_servers[j].servers[i];
      readers[i] <- mkMemReadInternal(client_bins[i],indication,ss);
   end

   rule mmuEntry;
      addrReqFifo.deq;
      let physAddr <- mmus[addrReqFifo.first[31:16]].addr[0].response.get;
      indication.addrResponse(zeroExtend(physAddr));
   endrule

   function PhysMemMaster#(addrWidth,dataWidth) mkm(Integer i) = (interface PhysMemMaster#(addrWidth,dataWidth);
								 interface PhysMemReadClient read_client = readers[i].read_client;
								 interface PhysMemWriteClient write_client = null_phys_mem_write_client;
							      endinterface);

   Stmt dbgStmt = seq
		     for(dbgPtr <= 0; dbgPtr < fromInteger(valueOf(nMasters)); dbgPtr <= dbgPtr+1)
			(action
			    let rv <- readers[dbgPtr].dbg.dbg;
			    indication.reportStateDbg(rv);
			 endaction);
		  endseq;
   FSM dbgFSM <- mkFSM(dbgStmt);

   Stmt trafficStmt = seq
			 trafficAccum <= 0;
			 for(trafficPtr <= 0; trafficPtr < fromInteger(valueOf(nMasters)); trafficPtr <= trafficPtr+1)
			    (action
				let rv <- readers[trafficPtr].dbg.getMemoryTraffic();
				trafficAccum <= trafficAccum + rv;
			     endaction);
			 indication.reportMemoryTraffic(trafficAccum);
		      endseq;
   FSM trafficFSM <- mkFSM(trafficStmt);

   interface MemServerRequest request;
      method Action stateDbg(ChannelType rc);
	 if (rc == Read)
	    dbgFSM.start;
      endmethod
      method Action memoryTraffic(ChannelType rc);
	 if (rc == Read)
	    trafficFSM.start;
      endmethod
      method Action addrTrans(Bit#(32) pointer, Bit#(32) offset);
	 addrReqFifo.enq(pointer);
	 mmus[pointer[31:16]].addr[0].request.put(ReqTup{id:truncate(pointer), off:extend(offset)});
      endmethod
   endinterface
   interface masters = map(mkm,genVector);
endmodule

module mkMemServerW#(MemServerIndication indication,
		     Vector#(numWriteClients, MemWriteClient#(dataWidth)) writeClients,
		     Vector#(numMMUs,MMU#(PhysAddrWidth)) mmus)
   (MemServer#(PhysAddrWidth, dataWidth, nMasters))

   provisos (Add#(1,a__,dataWidth),
	     Mul#(TDiv#(dataWidth, 8), 8, dataWidth),
	     Mul#(nwc, nMasters, numWriteClients),
	     Add#(b__, TLog#(nwc), 6)
	     );

   FIFO#(Bit#(32))   addrReqFifo <- mkFIFO;
   Reg#(Bit#(8)) dbgPtr <- mkReg(0);
   Reg#(Bit#(8)) trafficPtr <- mkReg(0);
   Reg#(Bit#(64)) trafficAccum <- mkReg(0);

   function a selectClient(Vector#(n, a) in, Integer r, Integer i, Integer j); return in[j * r + i]; endfunction
   function Vector#(nwc, a) selectClients(Vector#(numWriteClients, a) vec, Integer m);
      return genWith(selectClient(vec, valueOf(nMasters), m));
   endfunction
   Vector#(nMasters,Vector#(nwc, MemWriteClient#(dataWidth))) client_bins = genWith(selectClients(writeClients));

   module foo#(Integer i) (MMUAddrServer#(PhysAddrWidth,nMasters));
      let rv <- mkMMUAddrServer(mmus[i].addr[1]);
      return rv;
   endmodule
   Vector#(numMMUs,MMUAddrServer#(PhysAddrWidth,nMasters)) mmu_servers <- mapM(foo,genVector);

   Vector#(nMasters,MemWriteInternal#(PhysAddrWidth,dataWidth,MemServerTags)) writers;
   for(Integer i = 0; i < valueOf(nMasters); i = i+1) begin
      Vector#(numMMUs,Server#(ReqTup,Bit#(PhysAddrWidth))) ss;
      for(Integer j = 0; j < valueOf(numMMUs); j=j+1)
	 ss[j] = mmu_servers[j].servers[i];
      writers[i] <- mkMemWriteInternal(client_bins[i], indication, ss);
   end

   rule mmuEntry;
      addrReqFifo.deq;
      let physAddr <- mmus[addrReqFifo.first[31:16]].addr[1].response.get;
      indication.addrResponse(zeroExtend(physAddr));
   endrule

   function PhysMemMaster#(PhysAddrWidth,dataWidth) mkm(Integer i) = (interface PhysMemMaster#(PhysAddrWidth,dataWidth);
								 interface PhysMemReadClient read_client = null_phys_mem_read_client;
								 interface PhysMemWriteClient write_client = writers[i].write_client;
							      endinterface);

   Stmt dbgStmt = seq
		     for(dbgPtr <= 0; dbgPtr < fromInteger(valueOf(nMasters)); dbgPtr <= dbgPtr+1)
			(action
			    let rv <- writers[dbgPtr].dbg.dbg;
			    indication.reportStateDbg(rv);
			 endaction);
		  endseq;
   FSM dbgFSM <- mkFSM(dbgStmt);

   Stmt trafficStmt = seq
			 trafficAccum <= 0;
			 for(trafficPtr <= 0; trafficPtr < fromInteger(valueOf(nMasters)); trafficPtr <= trafficPtr+1)
			    (action
				let rv <- writers[trafficPtr].dbg.getMemoryTraffic();
				trafficAccum <= trafficAccum + rv;
			     endaction);
			 indication.reportMemoryTraffic(trafficAccum);
		      endseq;
   FSM trafficFSM <- mkFSM(trafficStmt);

   interface MemServerRequest request;
      method Action stateDbg(ChannelType rc);
	 if (rc == Write)
	    dbgFSM.start;
      endmethod
      method Action memoryTraffic(ChannelType rc);
	 if (rc == Write)
	    trafficFSM.start;
      endmethod
      method Action addrTrans(Bit#(32) pointer, Bit#(32) offset);
	 addrReqFifo.enq(pointer);
	 mmus[pointer[31:16]].addr[1].request.put(ReqTup{id:truncate(pointer), off:extend(offset)});
      endmethod
   endinterface
   interface masters = map(mkm,genVector);
endmodule

interface SimpleMemServer#(numeric type addrWidth, numeric type dataWidth, numeric type nMasters);
   interface MemServerRequest memServerRequest;
   interface MMURequest mmuRequest;
   interface Vector#(nMasters,PhysMemMaster#(addrWidth, dataWidth)) masters;
   interface Vector#(2,Server#(ReqTup,Bit#(addrWidth))) addr;
endinterface

module mkSimpleMemServer#(Vector#(numReadClients, MemReadClient#(dataWidth)) readClients,
			  Vector#(numWriteClients, MemWriteClient#(dataWidth)) writeClients,
			  MemServerIndication indication,
			  MMUIndication mmuIndication)(SimpleMemServer#(PhysAddrWidth, dataWidth,nMasters))
   provisos (Max#(nMasters,numReadClients,numReadClientsActual),
	     Add#(numReadClients,numReadClientsNull,numReadClientsActual),
	     Mul#(a__, nMasters, numReadClientsActual),
	     Max#(nMasters,numWriteClients,numWriteClientsActual),
	     Add#(numWriteClients,numWriteClientsNull,numWriteClientsActual),
	     Mul#(b__, nMasters, numWriteClientsActual),
	     Add#(TLog#(TDiv#(dataWidth, 8)), c__, 10),
	     Add#(d__, TLog#(b__), 6),
	     Add#(e__, TLog#(a__), 6),
	     Mul#(TDiv#(dataWidth, 8), 8, dataWidth),
	     Add#(1, f__, dataWidth)
	     );

   MMU#(PhysAddrWidth) hostMMU <- mkMMU(0, True, mmuIndication);

   Vector#(numReadClientsNull, MemReadClient#(dataWidth)) nullReadClients = replicate(null_mem_read_client());
   Vector#(numWriteClientsNull, MemWriteClient#(dataWidth)) nullWriteClients = replicate(null_mem_write_client());

   MemServer#(PhysAddrWidth,dataWidth,nMasters) dma <- mkMemServerRW(indication, append(readClients,nullReadClients),
								     append(writeClients,nullWriteClients),
								     cons(hostMMU,nil));

   interface MemServerRequest memServerRequest = dma.request;
   interface MMURequest mmuRequest = hostMMU.request;
   interface Vector masters = dma.masters;
   interface Vector addr = hostMMU.addr;
endmodule

// Copyright (c) 2013 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

// BSV Libraries
import FIFO::*;
import Vector::*;
import List::*;
import GetPut::*;
import ClientServer::*;
import Assert::*;
import StmtFSM::*;

// CONNECTAL Libraries
import HostInterface::*;
import MemTypes::*;
import ConnectalMemory::*;
import MMU::*;
import MemServerInternal::*;

function Put#(t) null_put();
   return (interface Put;
              method Action put(t x) if (False);
                 noAction;
              endmethod
           endinterface);
endfunction

function Get#(t) null_get();
   return (interface Get;
              method ActionValue#(t) get() if (False);
                 return ?;
              endmethod
           endinterface);
endfunction

function  PhysMemWriteClient#(addrWidth, busWidth) null_mem_write_client();
   return (interface PhysMemWriteClient;
              interface Get writeReq = null_get;
              interface Get writeData = null_get;
              interface Put writeDone = null_put;
           endinterface);
endfunction

function  PhysMemReadClient#(addrWidth, busWidth) null_mem_read_client();
   return (interface PhysMemReadClient;
              interface Get readReq = null_get;
              interface Put readData = null_put;
           endinterface);
endfunction

interface MemServer#(numeric type addrWidth, numeric type dataWidth, numeric type nMasters);
   interface MemServerRequest request;
   interface Vector#(nMasters,PhysMemMaster#(addrWidth, dataWidth)) masters;
endinterface

typedef struct {
   DmaErrorType errorType;
   Bit#(32) pref;
   } DmaError deriving (Bits);

module mkMemServerRW#(MemServerIndication indication,
		      Vector#(numReadClients, MemReadClient#(dataWidth)) readClients,
		      Vector#(numWriteClients, MemWriteClient#(dataWidth)) writeClients,
		      Vector#(numMMUs,MMU#(PhysAddrWidth)) mmus)
   (MemServer#(PhysAddrWidth, dataWidth, nMasters))

   provisos (Add#(1,a__,dataWidth),
	     Mul#(TDiv#(dataWidth, 8), 8, dataWidth),
	     Mul#(nwc, nMasters, numWriteClients),
	     Mul#(nrc, nMasters, numReadClients),
	     Add#(b__, TLog#(nrc), 6),
	     Add#(c__, TLog#(nwc), 6),
	     Add#(TLog#(TDiv#(dataWidth, 8)), d__, BurstLenSize)
	     );

   MemServer#(PhysAddrWidth,dataWidth,nMasters) reader <- mkMemServerR(indication,  readClients, mmus);
   MemServer#(PhysAddrWidth,dataWidth,nMasters) writer <- mkMemServerW(indication, writeClients, mmus);

   function PhysMemMaster#(PhysAddrWidth,dataWidth) mkm(Integer i) = (interface PhysMemMaster#(PhysAddrWidth,dataWidth);
								 interface PhysMemReadClient read_client = reader.masters[i].read_client;
								 interface PhysMemWriteClient write_client = writer.masters[i].write_client;
							      endinterface);

   interface MemServerRequest request;
      method Action stateDbg(ChannelType rc);
	 if (rc == Read)
	    reader.request.stateDbg(rc);
	 else
	    writer.request.stateDbg(rc);
      endmethod
      method Action memoryTraffic(ChannelType rc);
	 if (rc == Read)
	    reader.request.memoryTraffic(rc);
	 else
	    writer.request.memoryTraffic(rc);
      endmethod
      method Action addrTrans(Bit#(32) pointer, Bit#(32) offset);
	 writer.request.addrTrans(pointer,offset);
      endmethod
   endinterface
   interface masters = map(mkm,genVector);
endmodule

module mkMemServerR#(MemServerIndication indication,
		       Vector#(numReadClients, MemReadClient#(dataWidth)) readClients,
		       Vector#(numMMUs,MMU#(addrWidth)) mmus)
   (MemServer#(addrWidth, dataWidth, nMasters))

   provisos (Add#(1,a__,dataWidth),
	     Mul#(TDiv#(dataWidth, 8), 8, dataWidth),
	     Mul#(nrc, nMasters, numReadClients),
	     Add#(b__, TLog#(nrc), 6),
	     Add#(TLog#(TDiv#(dataWidth, 8)), c__, BurstLenSize)
	     ,Add#(d__, addrWidth, 64)
	     ,Add#(e__, 12, addrWidth)
	     ,Add#(1, e__, f__)
	     );

   FIFO#(Bit#(32))   addrReqFifo <- mkFIFO;
   Reg#(Bit#(8)) dbgPtr <- mkReg(0);
   Reg#(Bit#(8)) trafficPtr <- mkReg(0);
   Reg#(Bit#(64)) trafficAccum <- mkReg(0);

   function a selectClient(Vector#(n, a) in, Integer r, Integer i, Integer j); return in[j * r + i]; endfunction
   function Vector#(nrc, a) selectClients(Vector#(numReadClients, a) vec, Integer m);
      return genWith(selectClient(vec, valueOf(nMasters), m));
   endfunction
   Vector#(nMasters,Vector#(nrc, MemReadClient#(dataWidth))) client_bins = genWith(selectClients(readClients));

   module foo#(Integer i) (MMUAddrServer#(addrWidth,nMasters));
      let rv <- mkMMUAddrServer(mmus[i].addr[0]);
      return rv;
   endmodule
   Vector#(numMMUs,MMUAddrServer#(addrWidth,nMasters)) mmu_servers <- mapM(foo,genVector);

   Vector#(nMasters,MemReadInternal#(addrWidth,dataWidth,MemServerTags)) readers;
   for(Integer i = 0; i < valueOf(nMasters); i = i+1) begin
      Vector#(numMMUs,Server#(ReqTup,Bit#(addrWidth))) ss;
      for(Integer j = 0; j < valueOf(numMMUs); j=j+1)
	 ss[j] = mmu_servers[j].servers[i];
      readers[i] <- mkMemReadInternal(client_bins[i],indication,ss);
   end

   rule mmuEntry;
      addrReqFifo.deq;
      let physAddr <- mmus[addrReqFifo.first[31:16]].addr[0].response.get;
      indication.addrResponse(zeroExtend(physAddr));
   endrule

   function PhysMemMaster#(addrWidth,dataWidth) mkm(Integer i) = (interface PhysMemMaster#(addrWidth,dataWidth);
								 interface PhysMemReadClient read_client = readers[i].read_client;
								 interface PhysMemWriteClient write_client = null_mem_write_client;
							      endinterface);

   Stmt dbgStmt = seq
		     for(dbgPtr <= 0; dbgPtr < fromInteger(valueOf(nMasters)); dbgPtr <= dbgPtr+1)
			(action
			    let rv <- readers[dbgPtr].dbg.dbg;
			    indication.reportStateDbg(rv);
			 endaction);
		  endseq;
   FSM dbgFSM <- mkFSM(dbgStmt);

   Stmt trafficStmt = seq
			 trafficAccum <= 0;
			 for(trafficPtr <= 0; trafficPtr < fromInteger(valueOf(nMasters)); trafficPtr <= trafficPtr+1)
			    (action
				let rv <- readers[trafficPtr].dbg.getMemoryTraffic();
				trafficAccum <= trafficAccum + rv;
			     endaction);
			 indication.reportMemoryTraffic(trafficAccum);
		      endseq;
   FSM trafficFSM <- mkFSM(trafficStmt);

   interface MemServerRequest request;
      method Action stateDbg(ChannelType rc);
	 if (rc == Read)
	    dbgFSM.start;
      endmethod
      method Action memoryTraffic(ChannelType rc);
	 if (rc == Read)
	    trafficFSM.start;
      endmethod
      method Action addrTrans(Bit#(32) pointer, Bit#(32) offset);
	 addrReqFifo.enq(pointer);
	 mmus[pointer[31:16]].addr[0].request.put(ReqTup{id:truncate(pointer), off:extend(offset)});
      endmethod
   endinterface
   interface masters = map(mkm,genVector);
endmodule

module mkMemServerW#(MemServerIndication indication,
		     Vector#(numWriteClients, MemWriteClient#(dataWidth)) writeClients,
		     Vector#(numMMUs,MMU#(PhysAddrWidth)) mmus)
   (MemServer#(PhysAddrWidth, dataWidth, nMasters))

   provisos (Add#(1,a__,dataWidth),
	     Mul#(TDiv#(dataWidth, 8), 8, dataWidth),
	     Mul#(nwc, nMasters, numWriteClients),
	     Add#(b__, TLog#(nwc), 6)
	     );

   FIFO#(Bit#(32))   addrReqFifo <- mkFIFO;
   Reg#(Bit#(8)) dbgPtr <- mkReg(0);
   Reg#(Bit#(8)) trafficPtr <- mkReg(0);
   Reg#(Bit#(64)) trafficAccum <- mkReg(0);

   function a selectClient(Vector#(n, a) in, Integer r, Integer i, Integer j); return in[j * r + i]; endfunction
   function Vector#(nwc, a) selectClients(Vector#(numWriteClients, a) vec, Integer m);
      return genWith(selectClient(vec, valueOf(nMasters), m));
   endfunction
   Vector#(nMasters,Vector#(nwc, MemWriteClient#(dataWidth))) client_bins = genWith(selectClients(writeClients));

   module foo#(Integer i) (MMUAddrServer#(PhysAddrWidth,nMasters));
      let rv <- mkMMUAddrServer(mmus[i].addr[1]);
      return rv;
   endmodule
   Vector#(numMMUs,MMUAddrServer#(PhysAddrWidth,nMasters)) mmu_servers <- mapM(foo,genVector);

   Vector#(nMasters,MemWriteInternal#(PhysAddrWidth,dataWidth,MemServerTags)) writers;
   for(Integer i = 0; i < valueOf(nMasters); i = i+1) begin
      Vector#(numMMUs,Server#(ReqTup,Bit#(PhysAddrWidth))) ss;
      for(Integer j = 0; j < valueOf(numMMUs); j=j+1)
	 ss[j] = mmu_servers[j].servers[i];
      writers[i] <- mkMemWriteInternal(client_bins[i], indication, ss);
   end

   rule mmuEntry;
      addrReqFifo.deq;
      let physAddr <- mmus[addrReqFifo.first[31:16]].addr[1].response.get;
      indication.addrResponse(zeroExtend(physAddr));
   endrule

   function PhysMemMaster#(PhysAddrWidth,dataWidth) mkm(Integer i) = (interface PhysMemMaster#(PhysAddrWidth,dataWidth);
								 interface PhysMemReadClient read_client = null_mem_read_client;
								 interface PhysMemWriteClient write_client = writers[i].write_client;
							      endinterface);

   Stmt dbgStmt = seq
		     for(dbgPtr <= 0; dbgPtr < fromInteger(valueOf(nMasters)); dbgPtr <= dbgPtr+1)
			(action
			    let rv <- writers[dbgPtr].dbg.dbg;
			    indication.reportStateDbg(rv);
			 endaction);
		  endseq;
   FSM dbgFSM <- mkFSM(dbgStmt);

   Stmt trafficStmt = seq
			 trafficAccum <= 0;
			 for(trafficPtr <= 0; trafficPtr < fromInteger(valueOf(nMasters)); trafficPtr <= trafficPtr+1)
			    (action
				let rv <- writers[trafficPtr].dbg.getMemoryTraffic();
				trafficAccum <= trafficAccum + rv;
			     endaction);
			 indication.reportMemoryTraffic(trafficAccum);
		      endseq;
   FSM trafficFSM <- mkFSM(trafficStmt);

   interface MemServerRequest request;
      method Action stateDbg(ChannelType rc);
	 if (rc == Write)
	    dbgFSM.start;
      endmethod
      method Action memoryTraffic(ChannelType rc);
	 if (rc == Write)
	    trafficFSM.start;
      endmethod
      method Action addrTrans(Bit#(32) pointer, Bit#(32) offset);
	 addrReqFifo.enq(pointer);
	 mmus[pointer[31:16]].addr[1].request.put(ReqTup{id:truncate(pointer), off:extend(offset)});
      endmethod
   endinterface
   interface masters = map(mkm,genVector);
endmodule