added interface MemServer

added interface MemServer

// 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 FIFOF::*;
import Adapter::*;
import Vector::*;
import Connectable::*;
import BRAMFIFO::*;
import GetPut::*;
import ClientServer::*;

import ConnectalConfig::*;
import Pipe::*;
import ConnectalMemory::*;
import DefaultValue::*;

`include "ConnectalProjectConfig.bsv"

typedef Bit#(32) SGLId;
typedef 44 MemOffsetSize;
`ifdef MemTagSize
typedef `MemTagSize MemTagSize;
`else
typedef 6 MemTagSize;
`endif
typedef `BurstLenSize BurstLenSize;

`ifndef USE_ACP
`ifdef PCIE3
// as configured, the Xilinx gen3 PCIe core supports 5 bit tags, and
// we need to use unique tags for all transactions in flight. Since
// MemServer uses the same tag numbers for reads and writes, we use
// tag[4] to distinguish the two, leaving 4 bits for unique tags.
// TODO: There is an option for longer tags in the gen3 core.
typedef 16 MemServerTags;
`else
typedef 32 MemServerTags;
`endif
`else
typedef 8 MemServerTags;
`endif
`ifdef DataBusWidth
typedef TDiv#(`DataBusWidth,8) ByteEnableSize;
`else
typedef TDiv#(64,8) ByteEnableSize;
`endif

// memory request with physical addresses.
// these can be transmitted directly to the bus master
typedef struct {
   Bit#(addrWidth) addr;
   Bit#(BurstLenSize) burstLen;
   Bit#(MemTagSize) tag;
`ifdef BYTE_ENABLES
   Bit#(TDiv#(dataBusWidth,8)) firstbe; // maybe we only need lastbe
   Bit#(TDiv#(dataBusWidth,8)) lastbe;
`endif
   } PhysMemRequest#(numeric type addrWidth, numeric type dataBusWidth) deriving (Bits);

instance DefaultValue#(PhysMemRequest#(addrWidth,dataBusWidth));
   defaultValue = PhysMemRequest { addr: 0, burstLen: 0, tag: 0
`ifdef BYTE_ENABLES
				  , firstbe: maxBound, lastbe: maxBound
`endif
      };
endinstance

// memory request with "virtual" addresses.
// these need to be translated before they can be send to the bus
typedef struct {
   SGLId sglId;
   Bit#(MemOffsetSize) offset;
   Bit#(BurstLenSize) burstLen;
   Bit#(MemTagSize)  tag;
`ifdef BYTE_ENABLES
   Bit#(ByteEnableSize) firstbe; // maybe we only need lastbe
   Bit#(ByteEnableSize) lastbe;
`endif
   } MemRequest deriving (Bits);

instance DefaultValue#(MemRequest);
   defaultValue = MemRequest {
      sglId: 0, offset: 0, burstLen: 0, tag: 0
`ifdef BYTE_ENABLES
      , firstbe: maxBound, lastbe: maxBound
`endif
      };
endinstance

// memory payload
typedef struct {
   Bit#(dsz) data;
   Bit#(MemTagSize) tag;
   Bool last;
   } MemData#(numeric type dsz) deriving (Bits);

typeclass ReqByteEnables#(type t, numeric type besz);
   function Bit#(besz) reqFirstByteEnable(t req);
   function Bit#(besz) reqLastByteEnable(t req);
endtypeclass
instance ReqByteEnables#(PhysMemRequest#(addrWidth,dataBusWidth),TDiv#(dataBusWidth,8));
`ifdef BYTE_ENABLES
   function Bit#(TDiv#(dataBusWidth,8)) reqFirstByteEnable(PhysMemRequest#(addrWidth,dataBusWidth) req); return req.firstbe; endfunction
   function Bit#(TDiv#(dataBusWidth,8)) reqLastByteEnable(PhysMemRequest#(addrWidth,dataBusWidth) req); return req.lastbe; endfunction
`else
   function Bit#(TDiv#(dataBusWidth,8)) reqFirstByteEnable(PhysMemRequest#(addrWidth,dataBusWidth) req); return maxBound; endfunction
   function Bit#(TDiv#(dataBusWidth,8)) reqLastByteEnable(PhysMemRequest#(addrWidth,dataBusWidth) req); return maxBound; endfunction
`endif
endinstance
instance ReqByteEnables#(MemRequest,ByteEnableSize);
`ifdef BYTE_ENABLES
   function Bit#(ByteEnableSize) reqFirstByteEnable(MemRequest req); return req.firstbe; endfunction
   function Bit#(ByteEnableSize) reqLastByteEnable(MemRequest req); return req.lastbe; endfunction
`else
   function Bit#(ByteEnableSize) reqFirstByteEnable(MemRequest req); return maxBound; endfunction
   function Bit#(ByteEnableSize) reqLastByteEnable(MemRequest req); return maxBound; endfunction
`endif
endinstance

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

typedef struct {SGLId sglId;
		Bit#(32) base;
		Bit#(BurstLenSize) burstLen;
		Bit#(32) len;
		Bit#(MemTagSize) tag;
		} MemengineCmd deriving (Eq,Bits);

interface MemWriteEngineServer#(numeric type userWidth);
   interface Put#(MemengineCmd)       request;
   interface Get#(Bool)               done;
   interface PipeIn#(Bit#(userWidth)) data;
   interface PipeOut#(MemRequestCycles)     requestCycles;
endinterface

interface MemWriteEngine#(numeric type busWidth, numeric type userWidth, numeric type cmdQDepth, numeric type numServers);
   interface MemWriteClient#(busWidth) dmaClient;
   interface Vector#(numServers, MemWriteEngineServer#(userWidth)) writeServers;
endinterface

typedef struct {
   Bit#(dsz) data;
   Bit#(MemTagSize) tag;
   Bool first;
   Bool last;
   } MemDataF#(numeric type dsz) deriving (Bits);

typedef struct {
   Bit#(MemTagSize) tag;
   Bit#(32)         cycles;
   } MemRequestCycles deriving (Bits);

interface MemReadEngineServer#(numeric type userWidth);
   interface Put#(MemengineCmd)             request;
   interface PipeOut#(MemDataF#(userWidth)) data;
   interface PipeOut#(MemRequestCycles)     requestCycles;
endinterface

interface MemReadEngine#(numeric type busWidth, numeric type userWidth, numeric type cmdQDepth, numeric type numServers);
   interface MemReadClient#(busWidth) dmaClient;
   interface Vector#(numServers, MemReadEngineServer#(userWidth)) readServers;
endinterface

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

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

interface MemReadClient#(numeric type dsz);
   interface Get#(MemRequest)    readReq;
   interface Put#(MemData#(dsz)) readData;
endinterface

interface MemWriteClient#(numeric type dsz);
   interface Get#(MemRequest)    writeReq;
   interface Get#(MemData#(dsz)) writeData;
   interface Put#(Bit#(MemTagSize))       writeDone;
endinterface

interface MemReadServer#(numeric type dsz);
   interface Put#(MemRequest) readReq;
   interface Get#(MemData#(dsz))     readData;
endinterface

interface MemWriteServer#(numeric type dsz);
   interface Put#(MemRequest) writeReq;
   interface Put#(MemData#(dsz))     writeData;
   interface Get#(Bit#(MemTagSize))           writeDone;
endinterface

interface MemServer#(numeric type dataWidth);
   interface MemReadServer#(dataWidth) readServer;
   interface MemWriteServer#(dataWidth) writeServer;
endinterface

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

interface PhysMemSlave#(numeric type addrWidth, numeric type dataWidth);
   interface PhysMemReadServer#(addrWidth, dataWidth) read_server;
   interface PhysMemWriteServer#(addrWidth, dataWidth) write_server;
endinterface

interface PhysMemMaster#(numeric type addrWidth, numeric type dataWidth);
   interface PhysMemReadClient#(addrWidth, dataWidth) read_client;
   interface PhysMemWriteClient#(addrWidth, dataWidth) write_client;
endinterface

interface PhysMemReadClient#(numeric type asz, numeric type dsz);
   interface Get#(PhysMemRequest#(asz,dsz))    readReq;
   interface Put#(MemData#(dsz)) readData;
endinterface

interface PhysMemWriteClient#(numeric type asz, numeric type dsz);
   interface Get#(PhysMemRequest#(asz,dsz))    writeReq;
   interface Get#(MemData#(dsz)) writeData;
   interface Put#(Bit#(MemTagSize))       writeDone;
endinterface

interface PhysMemReadServer#(numeric type asz, numeric type dsz);
   interface Put#(PhysMemRequest#(asz,dsz)) readReq;
   interface Get#(MemData#(dsz))     readData;
endinterface

interface PhysMemWriteServer#(numeric type asz, numeric type dsz);
   interface Put#(PhysMemRequest#(asz,dsz)) writeReq;
   interface Put#(MemData#(dsz))     writeData;
   interface Get#(Bit#(MemTagSize))           writeDone;
endinterface

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

instance Connectable#(MemReadClient#(dsz), MemReadServer#(dsz));
   module mkConnection#(MemReadClient#(dsz) source, MemReadServer#(dsz) sink)(Empty);
      rule mr_request;
	 let req <- source.readReq.get();
	 sink.readReq.put(req);
      endrule
      rule mr_response;
	 let resp <- sink.readData.get();
	 source.readData.put(resp);
      endrule
   endmodule
endinstance

instance Connectable#(MemWriteClient#(dsz), MemWriteServer#(dsz));
   module mkConnection#(MemWriteClient#(dsz) source, MemWriteServer#(dsz) sink)(Empty);
      rule mw_request;
	 let req <- source.writeReq.get();
	 sink.writeReq.put(req);
      endrule
      rule mw_response;
	 let resp <- source.writeData.get();
	 sink.writeData.put(resp);
      endrule
      rule mw_done;
	 let resp <- sink.writeDone.get();
	 source.writeDone.put(resp);
      endrule
   endmodule
endinstance

instance Connectable#(PhysMemMaster#(addrWidth, busWidth), PhysMemSlave#(addrWidth, busWidth));
   module mkConnection#(PhysMemMaster#(addrWidth, busWidth) m, PhysMemSlave#(addrWidth, busWidth) s)(Empty);
      mkConnection(m.read_client.readReq, s.read_server.readReq);
      mkConnection(s.read_server.readData, m.read_client.readData);
      mkConnection(m.write_client.writeReq, s.write_server.writeReq);
      mkConnection(m.write_client.writeData, s.write_server.writeData);
      mkConnection(s.write_server.writeDone, m.write_client.writeDone);
   endmodule
endinstance

// this is used for debugging MemToPcie/PcieToMem in BsimTop.bsv
instance Connectable#(PhysMemMaster#(32, busWidth), PhysMemSlave#(40, busWidth));
   module mkConnection#(PhysMemMaster#(32, busWidth) m, PhysMemSlave#(40, busWidth) s)(Empty);
      //mkConnection(m.read_client.readReq, s.read_server.readReq);
      rule readreq;
	 let req <- m.read_client.readReq.get();
	 s.read_server.readReq.put(PhysMemRequest { addr: extend(req.addr), burstLen: req.burstLen, tag: req.tag
`ifdef BYTE_ENABLES
						   , firstbe: req.firstbe, lastbe: req.lastbe
`endif
	    });
      endrule

      mkConnection(s.read_server.readData, m.read_client.readData);
      //mkConnection(m.write_client.writeReq, s.write_server.writeReq);
      rule writereq;
	 let req <- m.write_client.writeReq.get();
	 s.write_server.writeReq.put(PhysMemRequest { addr: extend(req.addr), burstLen: req.burstLen, tag: req.tag
`ifdef BYTE_ENABLES
						     , firstbe: req.firstbe, lastbe: req.lastbe
`endif
 });
      endrule
      mkConnection(m.write_client.writeData, s.write_server.writeData);
      mkConnection(s.write_server.writeDone, m.write_client.writeDone);
   endmodule
endinstance

function Bool isQuadWordAligned(Bit#(7) lower_addr);
   return (lower_addr[2:0]==3'b0);
endfunction

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

// 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 FIFOF::*;
import Adapter::*;
import Vector::*;
import Connectable::*;
import BRAMFIFO::*;
import GetPut::*;
import ClientServer::*;

import ConnectalConfig::*;
import Pipe::*;
import ConnectalMemory::*;
import DefaultValue::*;

`include "ConnectalProjectConfig.bsv"

typedef Bit#(32) SGLId;
typedef 44 MemOffsetSize;
`ifdef MemTagSize
typedef `MemTagSize MemTagSize;
`else
typedef 6 MemTagSize;
`endif
typedef `BurstLenSize BurstLenSize;

`ifndef USE_ACP
`ifdef PCIE3
// as configured, the Xilinx gen3 PCIe core supports 5 bit tags, and
// we need to use unique tags for all transactions in flight. Since
// MemServer uses the same tag numbers for reads and writes, we use
// tag[4] to distinguish the two, leaving 4 bits for unique tags.
// TODO: There is an option for longer tags in the gen3 core.
typedef 16 MemServerTags;
`else
typedef 32 MemServerTags;
`endif
`else
typedef 8 MemServerTags;
`endif
`ifdef DataBusWidth
typedef TDiv#(`DataBusWidth,8) ByteEnableSize;
`else
typedef TDiv#(64,8) ByteEnableSize;
`endif

// memory request with physical addresses.
// these can be transmitted directly to the bus master
typedef struct {
   Bit#(addrWidth) addr;
   Bit#(BurstLenSize) burstLen;
   Bit#(MemTagSize) tag;
`ifdef BYTE_ENABLES
   Bit#(TDiv#(dataBusWidth,8)) firstbe; // maybe we only need lastbe
   Bit#(TDiv#(dataBusWidth,8)) lastbe;
`endif
   } PhysMemRequest#(numeric type addrWidth, numeric type dataBusWidth) deriving (Bits);

instance DefaultValue#(PhysMemRequest#(addrWidth,dataBusWidth));
   defaultValue = PhysMemRequest { addr: 0, burstLen: 0, tag: 0
`ifdef BYTE_ENABLES
				  , firstbe: maxBound, lastbe: maxBound
`endif
      };
endinstance

// memory request with "virtual" addresses.
// these need to be translated before they can be send to the bus
typedef struct {
   SGLId sglId;
   Bit#(MemOffsetSize) offset;
   Bit#(BurstLenSize) burstLen;
   Bit#(MemTagSize)  tag;
`ifdef BYTE_ENABLES
   Bit#(ByteEnableSize) firstbe; // maybe we only need lastbe
   Bit#(ByteEnableSize) lastbe;
`endif
   } MemRequest deriving (Bits);

instance DefaultValue#(MemRequest);
   defaultValue = MemRequest {
      sglId: 0, offset: 0, burstLen: 0, tag: 0
`ifdef BYTE_ENABLES
      , firstbe: maxBound, lastbe: maxBound
`endif
      };
endinstance

// memory payload
typedef struct {
   Bit#(dsz) data;
   Bit#(MemTagSize) tag;
   Bool last;
   } MemData#(numeric type dsz) deriving (Bits);

typeclass ReqByteEnables#(type t, numeric type besz);
   function Bit#(besz) reqFirstByteEnable(t req);
   function Bit#(besz) reqLastByteEnable(t req);
endtypeclass
instance ReqByteEnables#(PhysMemRequest#(addrWidth,dataBusWidth),TDiv#(dataBusWidth,8));
`ifdef BYTE_ENABLES
   function Bit#(TDiv#(dataBusWidth,8)) reqFirstByteEnable(PhysMemRequest#(addrWidth,dataBusWidth) req); return req.firstbe; endfunction
   function Bit#(TDiv#(dataBusWidth,8)) reqLastByteEnable(PhysMemRequest#(addrWidth,dataBusWidth) req); return req.lastbe; endfunction
`else
   function Bit#(TDiv#(dataBusWidth,8)) reqFirstByteEnable(PhysMemRequest#(addrWidth,dataBusWidth) req); return maxBound; endfunction
   function Bit#(TDiv#(dataBusWidth,8)) reqLastByteEnable(PhysMemRequest#(addrWidth,dataBusWidth) req); return maxBound; endfunction
`endif
endinstance
instance ReqByteEnables#(MemRequest,ByteEnableSize);
`ifdef BYTE_ENABLES
   function Bit#(ByteEnableSize) reqFirstByteEnable(MemRequest req); return req.firstbe; endfunction
   function Bit#(ByteEnableSize) reqLastByteEnable(MemRequest req); return req.lastbe; endfunction
`else
   function Bit#(ByteEnableSize) reqFirstByteEnable(MemRequest req); return maxBound; endfunction
   function Bit#(ByteEnableSize) reqLastByteEnable(MemRequest req); return maxBound; endfunction
`endif
endinstance

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

typedef struct {SGLId sglId;
		Bit#(32) base;
		Bit#(BurstLenSize) burstLen;
		Bit#(32) len;
		Bit#(MemTagSize) tag;
		} MemengineCmd deriving (Eq,Bits);

interface MemWriteEngineServer#(numeric type userWidth);
   interface Put#(MemengineCmd)       request;
   interface Get#(Bool)               done;
   interface PipeIn#(Bit#(userWidth)) data;
   interface PipeOut#(MemRequestCycles)     requestCycles;
endinterface

interface MemWriteEngine#(numeric type busWidth, numeric type userWidth, numeric type cmdQDepth, numeric type numServers);
   interface MemWriteClient#(busWidth) dmaClient;
   interface Vector#(numServers, MemWriteEngineServer#(userWidth)) writeServers;
endinterface

typedef struct {
   Bit#(dsz) data;
   Bit#(MemTagSize) tag;
   Bool first;
   Bool last;
   } MemDataF#(numeric type dsz) deriving (Bits);

typedef struct {
   Bit#(MemTagSize) tag;
   Bit#(32)         cycles;
   } MemRequestCycles deriving (Bits);

interface MemReadEngineServer#(numeric type userWidth);
   interface Put#(MemengineCmd)             request;
   interface PipeOut#(MemDataF#(userWidth)) data;
   interface PipeOut#(MemRequestCycles)     requestCycles;
endinterface

interface MemReadEngine#(numeric type busWidth, numeric type userWidth, numeric type cmdQDepth, numeric type numServers);
   interface MemReadClient#(busWidth) dmaClient;
   interface Vector#(numServers, MemReadEngineServer#(userWidth)) readServers;
endinterface

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

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

interface MemReadClient#(numeric type dsz);
   interface Get#(MemRequest)    readReq;
   interface Put#(MemData#(dsz)) readData;
endinterface

interface MemWriteClient#(numeric type dsz);
   interface Get#(MemRequest)    writeReq;
   interface Get#(MemData#(dsz)) writeData;
   interface Put#(Bit#(MemTagSize))       writeDone;
endinterface

interface MemReadServer#(numeric type dsz);
   interface Put#(MemRequest) readReq;
   interface Get#(MemData#(dsz))     readData;
endinterface

interface MemWriteServer#(numeric type dsz);
   interface Put#(MemRequest) writeReq;
   interface Put#(MemData#(dsz))     writeData;
   interface Get#(Bit#(MemTagSize))           writeDone;
endinterface

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

interface PhysMemSlave#(numeric type addrWidth, numeric type dataWidth);
   interface PhysMemReadServer#(addrWidth, dataWidth) read_server;
   interface PhysMemWriteServer#(addrWidth, dataWidth) write_server;
endinterface

interface PhysMemMaster#(numeric type addrWidth, numeric type dataWidth);
   interface PhysMemReadClient#(addrWidth, dataWidth) read_client;
   interface PhysMemWriteClient#(addrWidth, dataWidth) write_client;
endinterface

interface PhysMemReadClient#(numeric type asz, numeric type dsz);
   interface Get#(PhysMemRequest#(asz,dsz))    readReq;
   interface Put#(MemData#(dsz)) readData;
endinterface

interface PhysMemWriteClient#(numeric type asz, numeric type dsz);
   interface Get#(PhysMemRequest#(asz,dsz))    writeReq;
   interface Get#(MemData#(dsz)) writeData;
   interface Put#(Bit#(MemTagSize))       writeDone;
endinterface

interface PhysMemReadServer#(numeric type asz, numeric type dsz);
   interface Put#(PhysMemRequest#(asz,dsz)) readReq;
   interface Get#(MemData#(dsz))     readData;
endinterface

interface PhysMemWriteServer#(numeric type asz, numeric type dsz);
   interface Put#(PhysMemRequest#(asz,dsz)) writeReq;
   interface Put#(MemData#(dsz))     writeData;
   interface Get#(Bit#(MemTagSize))           writeDone;
endinterface

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

instance Connectable#(MemReadClient#(dsz), MemReadServer#(dsz));
   module mkConnection#(MemReadClient#(dsz) source, MemReadServer#(dsz) sink)(Empty);
      rule mr_request;
	 let req <- source.readReq.get();
	 sink.readReq.put(req);
      endrule
      rule mr_response;
	 let resp <- sink.readData.get();
	 source.readData.put(resp);
      endrule
   endmodule
endinstance

instance Connectable#(MemWriteClient#(dsz), MemWriteServer#(dsz));
   module mkConnection#(MemWriteClient#(dsz) source, MemWriteServer#(dsz) sink)(Empty);
      rule mw_request;
	 let req <- source.writeReq.get();
	 sink.writeReq.put(req);
      endrule
      rule mw_response;
	 let resp <- source.writeData.get();
	 sink.writeData.put(resp);
      endrule
      rule mw_done;
	 let resp <- sink.writeDone.get();
	 source.writeDone.put(resp);
      endrule
   endmodule
endinstance

instance Connectable#(PhysMemMaster#(addrWidth, busWidth), PhysMemSlave#(addrWidth, busWidth));
   module mkConnection#(PhysMemMaster#(addrWidth, busWidth) m, PhysMemSlave#(addrWidth, busWidth) s)(Empty);
      mkConnection(m.read_client.readReq, s.read_server.readReq);
      mkConnection(s.read_server.readData, m.read_client.readData);
      mkConnection(m.write_client.writeReq, s.write_server.writeReq);
      mkConnection(m.write_client.writeData, s.write_server.writeData);
      mkConnection(s.write_server.writeDone, m.write_client.writeDone);
   endmodule
endinstance

// this is used for debugging MemToPcie/PcieToMem in BsimTop.bsv
instance Connectable#(PhysMemMaster#(32, busWidth), PhysMemSlave#(40, busWidth));
   module mkConnection#(PhysMemMaster#(32, busWidth) m, PhysMemSlave#(40, busWidth) s)(Empty);
      //mkConnection(m.read_client.readReq, s.read_server.readReq);
      rule readreq;
	 let req <- m.read_client.readReq.get();
	 s.read_server.readReq.put(PhysMemRequest { addr: extend(req.addr), burstLen: req.burstLen, tag: req.tag
`ifdef BYTE_ENABLES
						   , firstbe: req.firstbe, lastbe: req.lastbe
`endif
	    });
      endrule

      mkConnection(s.read_server.readData, m.read_client.readData);
      //mkConnection(m.write_client.writeReq, s.write_server.writeReq);
      rule writereq;
	 let req <- m.write_client.writeReq.get();
	 s.write_server.writeReq.put(PhysMemRequest { addr: extend(req.addr), burstLen: req.burstLen, tag: req.tag
`ifdef BYTE_ENABLES
						     , firstbe: req.firstbe, lastbe: req.lastbe
`endif
 });
      endrule
      mkConnection(m.write_client.writeData, s.write_server.writeData);
      mkConnection(s.write_server.writeDone, m.write_client.writeDone);
   endmodule
endinstance

function Bool isQuadWordAligned(Bit#(7) lower_addr);
   return (lower_addr[2:0]==3'b0);
endfunction

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


use mkSimpleMMU in mkPlatform if USE_SIMPLE_MMU is defined.

// Copyright (c) 2015 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 ConnectalConfig::*;
import Vector::*;
import BuildVector::*;
import Portal::*;
import HostInterface::*;
import MMU::*;
import MemServer::*;
import MemTypes::*;
import CtrlMux::*;
import FIFO::*;
import GetPut::*;
import SpecialFIFOs::*;
import Pipe::*;
import ConnectalMemory::*;
import MMURequest::*;
import MMUIndication::*;
import MemServerIndication::*;
import MemServerRequest::*;
import IfcNames::*;
`include "ConnectalProjectConfig.bsv"
import `PinTypeInclude::*;

interface Platform;
   interface PhysMemSlave#(32,32) slave;
   interface Vector#(NumberOfMasters,PhysMemMaster#(PhysAddrWidth, DataBusWidth)) masters;
   interface Vector#(MaxNumberOfPortals,ReadOnly#(Bool)) interrupt;
   interface `PinType pins;
endinterface

typedef TMax#(TLog#(TSub#(NumberOfTiles,1)),1) TileTagBits;
function Bit#(TSub#(MemTagSize,TileTagBits)) tagLsb(Bit#(MemTagSize) tag); return truncate(tag); endfunction
function Bit#(TileTagBits) tagMsb(Bit#(MemTagSize) tag); return truncate(tag >> valueOf(TSub#(MemTagSize,TileTagBits))); endfunction

module renameReads#(Integer tile, MemReadClient#(DataBusWidth) reader, MemServerIndication err)(MemReadClient#(DataBusWidth));
   interface Get readReq;
      method ActionValue#(MemRequest) get;
	 let req <- reader.readReq.get;
	 Bit#(TSub#(MemTagSize,TileTagBits)) lsb = tagLsb(req.tag);
	 Bit#(TileTagBits) msb = tagMsb(req.tag);
	 if(req.tag != extend(lsb) && valueOf(NumberOfTiles) > 2) begin // one mgmt tile and one user tile
	    $display("renameReads tile tag out of range: 'h%h", req.tag);
	    err.error(extend(pack(DmaErrorTileTagOutOfRange)), req.sglId, extend(req.tag), fromInteger(tile));
	 end
	 req.tag = {fromInteger(tile),lsb};
	 return req;
      endmethod
   endinterface
   interface Put readData;
      method Action put(MemData#(DataBusWidth) v);
	 reader.readData.put(MemData{data:v.data, tag:{0,tagLsb(v.tag)}, last:v.last});
      endmethod
   endinterface
endmodule

module renameWrites#(Integer tile, MemWriteClient#(DataBusWidth) writer, MemServerIndication err)(MemWriteClient#(DataBusWidth));
   interface Get writeReq;
      method ActionValue#(MemRequest) get;
	 let req <- writer.writeReq.get;
	 Bit#(TSub#(MemTagSize,TileTagBits)) lsb = tagLsb(req.tag);
	 Bit#(TileTagBits) msb = tagMsb(req.tag);
	 if(req.tag != extend(lsb) && valueOf(NumberOfTiles) > 2) begin // one mgmt tile and one user tile
	    $display("renameWrites tile tag out of range: 'h%h", req.tag);
	    err.error(extend(pack(DmaErrorTileTagOutOfRange)), req.sglId, extend(req.tag), fromInteger(tile));
	 end
	 req.tag = {fromInteger(tile),lsb};
	 return req;
      endmethod
   endinterface
   interface Get writeData;
      method ActionValue#(MemData#(DataBusWidth)) get;
	 let rv <- writer.writeData.get;
   	 return MemData{data:rv.data, tag:{0,tagLsb(rv.tag)}, last:rv.last};
      endmethod
   endinterface
   interface Put writeDone;
      method Action put(Bit#(MemTagSize) v);
	 writer.writeDone.put({0,tagLsb(v)});
      endmethod
   endinterface
endmodule

module mkPlatform#(Vector#(NumberOfUserTiles, ConnectalTop) tiles)(Platform);
   /////////////////////////////////////////////////////////////
   // connecting up the tiles

   Vector#(NumberOfUserTiles, PhysMemSlave#(18,32)) tile_slaves;
   Vector#(NumberOfUserTiles, ReadOnly#(Bool)) tile_interrupts;
   Vector#(NumberOfUserTiles, Vector#(NumReadClients, MemReadClient#(DataBusWidth))) tile_read_clients;
   Vector#(NumberOfUserTiles, Vector#(NumWriteClients, MemWriteClient#(DataBusWidth))) tile_write_clients;
   Vector#(NumberOfUserTiles, Vector#(NumReadClients, Integer)) read_client_tile_numbers;
   Vector#(NumberOfUserTiles, Vector#(NumWriteClients, Integer)) write_client_tile_numbers;
   for(Integer i = 0; i < valueOf(NumberOfUserTiles); i=i+1) begin
      tile_slaves[i] = tiles[i].slave;
      let imux <- mkInterruptMux(tiles[i].interrupt);
      //ReadOnly#(Bool) imux = tiles[i].interrupt;
      tile_interrupts[i] = imux;
      tile_read_clients[i] = tiles[i].readers;
      tile_write_clients[i] = tiles[i].writers;
      read_client_tile_numbers[i] = replicate(i);
      write_client_tile_numbers[i] = replicate(i);
   end

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

   MMUIndicationProxy lMMUIndicationProxy <- mkMMUIndicationProxy(PlatformIfcNames_MMUIndicationH2S);
   MemServerIndicationProxy lMemServerIndicationProxy <- mkMemServerIndicationProxy(PlatformIfcNames_MemServerIndicationH2S);

`ifdef USE_SIMPLE_MMU
   MMU#(PhysAddrWidth) lMMU <- mkSimpleMMU(0,True, lMMUIndicationProxy.ifc);
`else
   MMU#(PhysAddrWidth) lMMU <- mkMMU(0,True, lMMUIndicationProxy.ifc);
`endif
   Vector#(TMul#(NumberOfUserTiles,NumReadClients), MemReadClient#(DataBusWidth)) tile_read_clients_renamed <- zipWith3M(renameReads, concat(read_client_tile_numbers), concat(tile_read_clients), replicate(lMemServerIndicationProxy.ifc));
   Vector#(TMul#(NumberOfUserTiles,NumWriteClients), MemWriteClient#(DataBusWidth)) tile_write_clients_renamed <- zipWith3M(renameWrites, concat(write_client_tile_numbers), concat(tile_write_clients), replicate(lMemServerIndicationProxy.ifc));
   MemServer#(PhysAddrWidth,DataBusWidth,NumberOfMasters) lMemServer <- mkMemServer(tile_read_clients_renamed, tile_write_clients_renamed, vec(lMMU), lMemServerIndicationProxy.ifc);

   MMURequestWrapper lMMURequestWrapper <- mkMMURequestWrapper(PlatformIfcNames_MMURequestS2H, lMMU.request);
   MemServerRequestWrapper lMemServerRequestWrapper <- mkMemServerRequestWrapper(PlatformIfcNames_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));

   /////////////////////////////////////////////////////////////
   // expose interface to top

   PhysMemSlave#(32,32) ctrl_mux <- mkPhysMemSlaveMux(cons(framework_ctrl_mux,tile_slaves));
   Vector#(MaxNumberOfPortals, ReadOnly#(Bool)) interrupts = replicate(interface ReadOnly; method Bool _read(); return False; endmethod endinterface);
   interrupts[0] = framework_intr;
   for (Integer i = 1; i < valueOf(NumberOfTiles); i = i + 1)
      interrupts[i] = tile_interrupts[i-1];
   interface interrupt = interrupts;
   interface slave = ctrl_mux;
   interface masters = lMemServer.masters;
   interface pins = tiles[0].pins;
endmodule

// Copyright (c) 2015 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 ConnectalConfig::*;
import Vector::*;
import BuildVector::*;
import Portal::*;
import HostInterface::*;
import MMU::*;
import MemServer::*;
import MemTypes::*;
import CtrlMux::*;
import FIFO::*;
import GetPut::*;
import SpecialFIFOs::*;
import Pipe::*;
import ConnectalMemory::*;
import MMURequest::*;
import MMUIndication::*;
import MemServerIndication::*;
import MemServerRequest::*;
import IfcNames::*;
`include "ConnectalProjectConfig.bsv"
import `PinTypeInclude::*;

interface Platform;
   interface PhysMemSlave#(32,32) slave;
   interface Vector#(NumberOfMasters,PhysMemMaster#(PhysAddrWidth, DataBusWidth)) masters;
   interface Vector#(MaxNumberOfPortals,ReadOnly#(Bool)) interrupt;
   interface `PinType pins;
endinterface

typedef TMax#(TLog#(TSub#(NumberOfTiles,1)),1) TileTagBits;
function Bit#(TSub#(MemTagSize,TileTagBits)) tagLsb(Bit#(MemTagSize) tag); return truncate(tag); endfunction
function Bit#(TileTagBits) tagMsb(Bit#(MemTagSize) tag); return truncate(tag >> valueOf(TSub#(MemTagSize,TileTagBits))); endfunction

module renameReads#(Integer tile, MemReadClient#(DataBusWidth) reader, MemServerIndication err)(MemReadClient#(DataBusWidth));
   interface Get readReq;
      method ActionValue#(MemRequest) get;
	 let req <- reader.readReq.get;
	 Bit#(TSub#(MemTagSize,TileTagBits)) lsb = tagLsb(req.tag);
	 Bit#(TileTagBits) msb = tagMsb(req.tag);
	 if(req.tag != extend(lsb) && valueOf(NumberOfTiles) > 2) begin // one mgmt tile and one user tile
	    $display("renameReads tile tag out of range: 'h%h", req.tag);
	    err.error(extend(pack(DmaErrorTileTagOutOfRange)), req.sglId, extend(req.tag), fromInteger(tile));
	 end
	 req.tag = {fromInteger(tile),lsb};
	 return req;
      endmethod
   endinterface
   interface Put readData;
      method Action put(MemData#(DataBusWidth) v);
	 reader.readData.put(MemData{data:v.data, tag:{0,tagLsb(v.tag)}, last:v.last});
      endmethod
   endinterface
endmodule

module renameWrites#(Integer tile, MemWriteClient#(DataBusWidth) writer, MemServerIndication err)(MemWriteClient#(DataBusWidth));
   interface Get writeReq;
      method ActionValue#(MemRequest) get;
	 let req <- writer.writeReq.get;
	 Bit#(TSub#(MemTagSize,TileTagBits)) lsb = tagLsb(req.tag);
	 Bit#(TileTagBits) msb = tagMsb(req.tag);
	 if(req.tag != extend(lsb) && valueOf(NumberOfTiles) > 2) begin // one mgmt tile and one user tile
	    $display("renameWrites tile tag out of range: 'h%h", req.tag);
	    err.error(extend(pack(DmaErrorTileTagOutOfRange)), req.sglId, extend(req.tag), fromInteger(tile));
	 end
	 req.tag = {fromInteger(tile),lsb};
	 return req;
      endmethod
   endinterface
   interface Get writeData;
      method ActionValue#(MemData#(DataBusWidth)) get;
	 let rv <- writer.writeData.get;
   	 return MemData{data:rv.data, tag:{0,tagLsb(rv.tag)}, last:rv.last};
      endmethod
   endinterface
   interface Put writeDone;
      method Action put(Bit#(MemTagSize) v);
	 writer.writeDone.put({0,tagLsb(v)});
      endmethod
   endinterface
endmodule

module mkPlatform#(Vector#(NumberOfUserTiles, ConnectalTop) tiles)(Platform);
   /////////////////////////////////////////////////////////////
   // connecting up the tiles

   Vector#(NumberOfUserTiles, PhysMemSlave#(18,32)) tile_slaves;
   Vector#(NumberOfUserTiles, ReadOnly#(Bool)) tile_interrupts;
   Vector#(NumberOfUserTiles, Vector#(NumReadClients, MemReadClient#(DataBusWidth))) tile_read_clients;
   Vector#(NumberOfUserTiles, Vector#(NumWriteClients, MemWriteClient#(DataBusWidth))) tile_write_clients;
   Vector#(NumberOfUserTiles, Vector#(NumReadClients, Integer)) read_client_tile_numbers;
   Vector#(NumberOfUserTiles, Vector#(NumWriteClients, Integer)) write_client_tile_numbers;
   for(Integer i = 0; i < valueOf(NumberOfUserTiles); i=i+1) begin
      tile_slaves[i] = tiles[i].slave;
      let imux <- mkInterruptMux(tiles[i].interrupt);
      //ReadOnly#(Bool) imux = tiles[i].interrupt;
      tile_interrupts[i] = imux;
      tile_read_clients[i] = tiles[i].readers;
      tile_write_clients[i] = tiles[i].writers;
      read_client_tile_numbers[i] = replicate(i);
      write_client_tile_numbers[i] = replicate(i);
   end

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

   MMUIndicationProxy lMMUIndicationProxy <- mkMMUIndicationProxy(PlatformIfcNames_MMUIndicationH2S);
   MemServerIndicationProxy lMemServerIndicationProxy <- mkMemServerIndicationProxy(PlatformIfcNames_MemServerIndicationH2S);

   MMU#(PhysAddrWidth) lMMU <- mkMMU(0,True, lMMUIndicationProxy.ifc);
   Vector#(TMul#(NumberOfUserTiles,NumReadClients), MemReadClient#(DataBusWidth)) tile_read_clients_renamed <- zipWith3M(renameReads, concat(read_client_tile_numbers), concat(tile_read_clients), replicate(lMemServerIndicationProxy.ifc));
   Vector#(TMul#(NumberOfUserTiles,NumWriteClients), MemWriteClient#(DataBusWidth)) tile_write_clients_renamed <- zipWith3M(renameWrites, concat(write_client_tile_numbers), concat(tile_write_clients), replicate(lMemServerIndicationProxy.ifc));
   MemServer#(PhysAddrWidth,DataBusWidth,NumberOfMasters) lMemServer <- mkMemServer(tile_read_clients_renamed, tile_write_clients_renamed, vec(lMMU), lMemServerIndicationProxy.ifc);

   MMURequestWrapper lMMURequestWrapper <- mkMMURequestWrapper(PlatformIfcNames_MMURequestS2H, lMMU.request);
   MemServerRequestWrapper lMemServerRequestWrapper <- mkMemServerRequestWrapper(PlatformIfcNames_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));

   /////////////////////////////////////////////////////////////
   // expose interface to top

   PhysMemSlave#(32,32) ctrl_mux <- mkPhysMemSlaveMux(cons(framework_ctrl_mux,tile_slaves));
   Vector#(MaxNumberOfPortals, ReadOnly#(Bool)) interrupts = replicate(interface ReadOnly; method Bool _read(); return False; endmethod endinterface);
   interrupts[0] = framework_intr;
   for (Integer i = 1; i < valueOf(NumberOfTiles); i = i + 1)
      interrupts[i] = tile_interrupts[i-1];
   interface interrupt = interrupts;
   interface slave = ctrl_mux;
   interface masters = lMemServer.masters;
   interface pins = tiles[0].pins;
endmodule


split rx and tx

split rx and tx

// Copyright (c) 2015 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.

// This file is a hand-generated file that we hope will someday be
// generated automatically by connectal/generated/scripts/importbvi.py
//
// Created by copying the style of connectal/generated/xilinx/PPS7LIB.bsv

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

// The name of this interface is a prefix "Par_" plus the common
// prefix of the signals "tx"
// Hopefully this is what importbvi.py would do
(* always_ready, always_enabled *)
interface Par_txo;
   method Action data_p(Bit#(8) v);
   method Action data_n(Bit#(8) v);
   method Action frame_p(Bit#(1) v);
   method Action frame_n(Bit#(1) v);
   method Action lclk_p(Bit#(1) v);
   method Action lclk_n(Bit#(1) v);
endinterface

interface Par_txi;
   method Bit#(1) wr_wait_p();
   method Bit#(1) wr_wait_n();
   method Bit#(1) rd_wait_p();
   method Bit#(1) rd_wait_n();
endinterface

(* always_ready, always_enabled *)
interface Par_rxi;
   method Bit#(8) data_p();
   method Bit#(8) data_n();
   method Bit#(1) frame_p();
   method Bit#(1) frame_n();
   method Bit#(1) lclk_p();
   method Bit#(1) lclk_n();
endinterface

interface Par_rxo;
   method Action wr_wait_p(Bit#(1) v);
   method Action wr_wait_n(Bit#(1) v);
   method Action rd_wait_p(Bit#(1) v);
   method Action rd_wait_n(Bit#(1) v);
endinterface

(* always_ready, always_enabled *)
interface Par_misc;
   method Bit#(1) csysack();
   method Bit#(1) cactive();
   method Action csysreq(Bit#(1) v);
   method Bit#(1) reset_chip();
   method Bit#(1) reset_fpga();
   method Action cclk_p(Bit#(1) v);
   method Action cclk_n(Bit#(1) v);
endinterface

typedef AxiMasterBits#(32,64,6,Empty) ParSaxiHp;
typedef AxiSlaveBits#(32,32,12,Empty) ParMaxiGp;

(* always_ready, always_enabled *)
interface ELink;
   interface Par_txi txi;
   interface Par_txo txo;
   interface Par_rxi rxi;
   interface Par_rxo rxo;
   interface ParMaxiGp maxi;   // this will connect to a master
   interface ParSaxiHp saxi;  // this will connect to a slave
   interface Par_misc misc;
endinterface

import "BVI" elink =
module mkELink#(Clock maxiclk, Clock saxiclk,
   Reset maxiclk_reset, Reset saxiclk_reset,
   Reset maxireset, Reset saxireset,
   Reset reset_chip, Reset reset_fpga)(ELink);
   // default_clock clk();
   // default_reset rst();
   input_clock maxiclk(m_axi_aclk) = maxiclk;  // assigns the verilog m_axi_aclk
   input_clock saxiclk(s_axi_aclk) = saxiclk;  // assigns the verilog s_axi_aclk
   input_reset maxiclk_reset() = maxiclk_reset; /* from clock*/
   input_reset saxiclk_reset() = saxiclk_reset; /* from clock*/
   input_reset maxireset() = maxireset;
   input_reset saxireset() = saxireset;

   interface Par_misc misc;
      method csysack csysack();
      method cactive cactive();
      method reset_chip reset_chip();
      method reset_fpga reset_fpga();
      method csysreq(csysreq) enable((*inhigh*) EN_csysreq);
      method cclk_p(cclk_p) enable((*inhigh*) EN_cclk_p);
      method cclk_n(cclk_n) enable((*inhigh*) EN_cclk_n);
   endinterface

   interface Par_txo txo;
      method data_p(txo_data_p) enable((*inhigh*) EN_txo_data_p);
      method data_n(txo_data_n) enable((*inhigh*) EN_txo_data_n);
      method frame_p(txo_frame_p) enable((*inhigh*) EN_txo_frame_p);
      method frame_n(txo_frame_n) enable((*inhigh*) EN_txo_frame_n);
      method lclk_p(txo_lclk_p) enable((*inhigh*) EN_txo_lclk_p);
      method lclk_n(txo_lclk_n) enable((*inhigh*) EN_txo_lclk_n);
   endinterface

   interface Par_txi txi;
      method txi_wr_wait_p wr_wait_p();
      method txi_wr_wait_n wr_wait_n();
      method txi_rd_wait_p rd_wait_p();
      method txi_rd_wait_n rd_wait_n();
   endinterface

   interface Par_rxi rxi;
      method rxi_data_p data_p();
      method rxi_data_n data_n();
      method rxi_frame_p frame_p();
      method rxi_frame_n frame_n();
      method rxi_lclk_p lclk_p();
      method rxi_lclk_n lclk_n();
   endinterface

   interface Par_rxo rxo;
      method wr_wait_p(rxo_wr_wait_p) enable((*inhigh*) EN_rxo_wr_wait_p);
      method wr_wait_n(rxo_wr_wait_n) enable((*inhigh*) EN_rxo_wr_wait_n);
      method rd_wait_p(rxo_rd_wait_p) enable((*inhigh*) EN_rxo_rd_wait_p);
      method rd_wait_n(rxo_rd_wait_n) enable((*inhigh*) EN_rxo_rd_wait_n);
   endinterface

   interface ParSaxiHp saxi;
      method m_axi_araddr araddr() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arburst arburst() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arcache arcache() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_aresetn aresetn() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arid arid() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arlen arlen() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arlock arlock() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arprot arprot() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arqos arqos() clocked_by (saxiclk) reset_by(saxireset);
      method arready(m_axi_arready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_arready);
      method m_axi_arsize arsize() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arvalid arvalid() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awaddr awaddr() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awburst awburst() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awcache awcache() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awid awid() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awlen awlen() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awlock awlock() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awprot awprot() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awqos awqos() clocked_by (saxiclk) reset_by(saxireset);
      method awready(m_axi_awready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_awready);
      method m_axi_awsize awsize() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awvalid awvalid() clocked_by (saxiclk) reset_by(saxireset);
      method bid(m_axi_bid) enable((*inhigh*) EN_m_axi_bid);
      method m_axi_bready bready() clocked_by (saxiclk) reset_by(saxireset);
      method bresp(m_axi_bresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_bresp);
      method bvalid(m_axi_bvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_bvalid);
      method rdata(m_axi_rdata)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rdata);
      method rid(m_axi_rid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rid);
      method rlast(m_axi_rlast)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rlast);
      method m_axi_rready rready() clocked_by (saxiclk) reset_by(saxireset);
      method rresp(m_axi_rresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rresp);
      method rvalid(m_axi_rvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rvalid);
      method m_axi_wdata wdata() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_wid wid() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_wlast wlast() clocked_by (saxiclk) reset_by(saxireset);
      method wready(m_axi_wready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_wready);
      method m_axi_wstrb wstrb() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_wvalid wvalid() clocked_by (saxiclk) reset_by(saxireset);
   endinterface

   interface ParMaxiGp maxi;
      method araddr(s_axi_araddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_araddr);
      method arburst(s_axi_arburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arburst);
      method arcache(s_axi_arcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arcache);
      method s_axi_aresetn aresetn() clocked_by(maxiclk) reset_by(maxireset);
      method arid(s_axi_arid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arid);
      method arlen(s_axi_arlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arlen);
      method arlock(s_axi_arlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arlock);
      method arprot(s_axi_arprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arprot);
      method arqos(s_axi_arqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arqos);
      method s_axi_arready arready() clocked_by(maxiclk) reset_by(maxireset);
      method arsize(s_axi_arsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arsize);
      method arvalid(s_axi_arvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arvalid);
      method awaddr(s_axi_awaddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awaddr);
      method awburst(s_axi_awburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awburst);
      method awcache(s_axi_awcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awcache);
      method awid(s_axi_awid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awid);
      method awlen(s_axi_awlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awlen);
      method awlock(s_axi_awlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awlock);
      method awprot(s_axi_awprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awprot);
      method awqos(s_axi_awqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awqos);
      method s_axi_awready awready() clocked_by(maxiclk) reset_by(maxireset);
      method awsize(s_axi_awsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awsize);
      method awvalid(s_axi_awvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awvalid);
      method s_axi_bid bid() clocked_by(maxiclk) reset_by(maxireset);
      method bready(s_axi_bready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_bready);
      method s_axi_bresp bresp() clocked_by(maxiclk) reset_by(maxireset);
      method s_axi_bvalid bvalid() clocked_by(maxiclk) reset_by(maxireset);
      method s_axi_rdata rdata() clocked_by(maxiclk) reset_by(maxireset);
      method s_axi_rlast rlast() clocked_by(maxiclk) reset_by(maxireset);
      method rready(s_axi_rready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_rready);
      method s_axi_rresp rresp() clocked_by(maxiclk) reset_by(maxireset);
      method s_axi_rvalid rvalid() clocked_by(maxiclk) reset_by(maxireset);
      method wdata(s_axi_wdata) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wdata);
      method wid(s_axi_wid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wid);
      method wlast(s_axi_wlast) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wlast);
      method s_axi_wready wready() clocked_by(maxiclk) reset_by(maxireset);
      method wstrb(s_axi_wstrb) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wstrb);
      method wvalid(s_axi_wvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wvalid);
      method s_axi_rid rid() clocked_by(maxiclk) reset_by(maxireset);
   endinterface

schedule (
   misc.csysack, misc.cactive, misc.reset_chip, misc.reset_fpga, txo.data_p, txo.data_n,
   txo.frame_p, txo.frame_n, txo.lclk_p, txo.lclk_n, rxo.wr_wait_p,
   rxo.wr_wait_n, rxo.rd_wait_p, rxo.rd_wait_n, misc.cclk_p,
   misc.cclk_n, maxi.awid, maxi.awaddr, maxi.awlen, maxi.awsize,
   maxi.awburst, maxi.awlock, maxi.awcache, maxi.awprot,
   maxi.awvalid, saxi.awready, maxi.wid, maxi.wdata, maxi.wstrb,
   maxi.wlast, maxi.wvalid, saxi.wready, maxi.bready, saxi.bid,
   saxi.bresp, saxi.bvalid, maxi.arid, maxi.araddr, maxi.arlen,
   maxi.arsize, maxi.arburst, maxi.arlock, maxi.arcache,
   maxi.arprot, maxi.arvalid, saxi.arready, maxi.rready,
   saxi.rid, saxi.rdata, saxi.rresp, saxi.rlast, saxi.rvalid,
   maxi.awqos, maxi.arqos,
   // Inputs
   // clkin_100, saxi.aclk, maxi.aclk, reset,
   saxi.aresetn,
   maxi.aresetn, misc.csysreq, rxi.data_p, rxi.data_n, rxi.frame_p,
   rxi.frame_n, rxi.lclk_p, rxi.lclk_n, txi.wr_wait_p, txi.wr_wait_n,
   txi.rd_wait_p, txi.rd_wait_n, maxi.awready, saxi.awid,
   saxi.awaddr, saxi.awlen, saxi.awsize, saxi.awburst,
   saxi.awlock, saxi.awcache, saxi.awprot, saxi.awvalid,
   maxi.wready, saxi.wid, saxi.wdata, saxi.wstrb, saxi.wlast,
   saxi.wvalid, maxi.bid, maxi.bresp, maxi.bvalid, saxi.bready,
   maxi.arready, saxi.arid, saxi.araddr, saxi.arlen, saxi.arsize,
   saxi.arburst, saxi.arlock, saxi.arcache, saxi.arprot,
   saxi.arvalid, maxi.rid, maxi.rdata, maxi.rresp, maxi.rlast,
   maxi.rvalid, saxi.rready, saxi.awqos, saxi.arqos
) CF (
   misc.csysack, misc.cactive, misc.reset_chip, misc.reset_fpga, txo.data_p, txo.data_n,
   txo.frame_p, txo.frame_n, txo.lclk_p, txo.lclk_n, rxo.wr_wait_p,
   rxo.wr_wait_n, rxo.rd_wait_p, rxo.rd_wait_n, misc.cclk_p,
   misc.cclk_n, maxi.awid, maxi.awaddr, maxi.awlen, maxi.awsize,
   maxi.awburst, maxi.awlock, maxi.awcache, maxi.awprot,
   maxi.awvalid, saxi.awready, maxi.wid, maxi.wdata, maxi.wstrb,
   maxi.wlast, maxi.wvalid, saxi.wready, maxi.bready, saxi.bid,
   saxi.bresp, saxi.bvalid, maxi.arid, maxi.araddr, maxi.arlen,
   maxi.arsize, maxi.arburst, maxi.arlock, maxi.arcache,
   maxi.arprot, maxi.arvalid, saxi.arready, maxi.rready,
   saxi.rid, saxi.rdata, saxi.rresp, saxi.rlast, saxi.rvalid,
   maxi.awqos, maxi.arqos,
   // Inputs
   // clkin_100, saxi.aclk, maxi.aclk, reset,
   saxi.aresetn,
   maxi.aresetn, misc.csysreq, rxi.data_p, rxi.data_n, rxi.frame_p,
   rxi.frame_n, rxi.lclk_p, rxi.lclk_n, txi.wr_wait_p, txi.wr_wait_n,
   txi.rd_wait_p, txi.rd_wait_n, maxi.awready, saxi.awid,
   saxi.awaddr, saxi.awlen, saxi.awsize, saxi.awburst,
   saxi.awlock, saxi.awcache, saxi.awprot, saxi.awvalid,
   maxi.wready, saxi.wid, saxi.wdata, saxi.wstrb, saxi.wlast,
   saxi.wvalid, maxi.bid, maxi.bresp, maxi.bvalid, saxi.bready,
   maxi.arready, saxi.arid, saxi.araddr, saxi.arlen, saxi.arsize,
   saxi.arburst, saxi.arlock, saxi.arcache, saxi.arprot,
   saxi.arvalid, maxi.rid, maxi.rdata, maxi.rresp, maxi.rlast,
   maxi.rvalid, saxi.rready, saxi.awqos, saxi.arqos

   );

endmodule

// Copyright (c) 2015 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.

// This file is a hand-generated file that we hope will someday be
// generated automatically by connectal/generated/scripts/importbvi.py
//
// Created by copying the style of connectal/generated/xilinx/PPS7LIB.bsv

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

// The name of this interface is a prefix "Par_" plus the common
// prefix of the signals "tx"
// Hopefully this is what importbvi.py would do
(* always_ready, always_enabled *)
interface Par_txo;
   method Action data_p(Bit#(8) v);
   method Action data_n(Bit#(8) v);
   method Action frame_p(Bit#(1) v);
   method Action frame_n(Bit#(1) v);
   method Action lclk_p(Bit#(1) v);
   method Action lclk_n(Bit#(1) v);
endinterface

interface Par_txi;
   method Bit#(1) wr_wait_p();
   method Bit#(1) wr_wait_n();
   method Bit#(1) rd_wait_p();
   method Bit#(1) rd_wait_n();
endinterface

(* always_ready, always_enabled *)
interface Par_rxi;
   method Bit#(8) data_p();
   method Bit#(8) data_n();
   method Bit#(1) frame_p();
   method Bit#(1) frame_n();
   method Bit#(1) lclk_p();
   method Bit#(1) lclk_n();
endinterface

interface Par_Rxo
   method Action wr_wait_p(Bit#(1) v);
   method Action wr_wait_n(Bit#(1) v);
   method Action rd_wait_p(Bit#(1) v);
   method Action rd_wait_n(Bit#(1) v);
endinterface

(* always_ready, always_enabled *)
interface Par_misc;
   method Bit#(1) csysack();
   method Bit#(1) cactive();
   method Action csysreq(Bit#(1) v);
   method Bit#(1) reset_chip();
   method Bit#(1) reset_fpga();
   method Action cclk_p(Bit#(1) v);
   method Action cclk_n(Bit#(1) v);
endinterface

typedef AxiMasterBits#(32,64,6,Empty) ParSaxiHp;
typedef AxiSlaveBits#(32,32,12,Empty) ParMaxiGp;

(* always_ready, always_enabled *)
interface ELink;
   interface Par_txi txi;
   interface Par_txo txo;
   interface Par_rxi rxi;
   interface Par_rxo rxo;
   interface ParMaxiGp maxi;   // this will connect to a master
   interface ParSaxiHp saxi;  // this will connect to a slave
   interface Par_misc misc;
endinterface

import "BVI" elink =
module mkELink#(Clock maxiclk, Clock saxiclk,
   Reset maxiclk_reset, Reset saxiclk_reset,
   Reset maxireset, Reset saxireset,
   Reset reset_chip, Reset reset_fpga)(ELink);
   // default_clock clk();
   // default_reset rst();
   input_clock maxiclk(m_axi_aclk) = maxiclk;  // assigns the verilog m_axi_aclk
   input_clock saxiclk(s_axi_aclk) = saxiclk;  // assigns the verilog s_axi_aclk
   input_reset maxiclk_reset() = maxiclk_reset; /* from clock*/
   input_reset saxiclk_reset() = saxiclk_reset; /* from clock*/
   input_reset maxireset() = maxireset;
   input_reset saxireset() = saxireset;

   interface Par_misc misc;
      method csysack csysack();
      method cactive cactive();
      method reset_chip reset_chip();
      method reset_fpga reset_fpga();
      method csysreq(csysreq) enable((*inhigh*) EN_csysreq);
      method cclk_p(cclk_p) enable((*inhigh*) EN_cclk_p);
      method cclk_n(cclk_n) enable((*inhigh*) EN_cclk_n);
   endinterface

   interface Par_txo txo;
      method data_p(txo_data_p) enable((*inhigh*) EN_txo_data_p);
      method data_n(txo_data_n) enable((*inhigh*) EN_txo_data_n);
      method frame_p(txo_frame_p) enable((*inhigh*) EN_txo_frame_p);
      method frame_n(txo_frame_n) enable((*inhigh*) EN_txo_frame_n);
      method lclk_p(txo_lclk_p) enable((*inhigh*) EN_txo_lclk_p);
      method lclk_n(txo_lclk_n) enable((*inhigh*) EN_txo_lclk_n);
   endinterface

   interface Par_txi txi;
      method txi_wr_wait_p wr_wait_p();
      method txi_wr_wait_n wr_wait_n();
      method txi_rd_wait_p rd_wait_p();
      method txi_rd_wait_n rd_wait_n();
   endinterface

   interface Par_rxi rxi;
      method rxi_data_p data_p();
      method rxi_data_n data_n();
      method rxi_frame_p frame_p();
      method rxi_frame_n frame_n();
      method rxi_lclk_p lclk_p();
      method rxi_lclk_n lclk_n();
   endinterface

   interface Par_rxo rxo;
      method wr_wait_p(rxo_wr_wait_p) enable((*inhigh*) EN_rxo_wr_wait_p);
      method wr_wait_n(rxo_wr_wait_n) enable((*inhigh*) EN_rxo_wr_wait_n);
      method rd_wait_p(rxo_rd_wait_p) enable((*inhigh*) EN_rxo_rd_wait_p);
      method rd_wait_n(rxo_rd_wait_n) enable((*inhigh*) EN_rxo_rd_wait_n);
   endinterface

   interface ParSaxiHp saxi;
      method m_axi_araddr araddr() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arburst arburst() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arcache arcache() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_aresetn aresetn() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arid arid() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arlen arlen() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arlock arlock() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arprot arprot() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arqos arqos() clocked_by (saxiclk) reset_by(saxireset);
      method arready(m_axi_arready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_arready);
      method m_axi_arsize arsize() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_arvalid arvalid() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awaddr awaddr() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awburst awburst() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awcache awcache() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awid awid() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awlen awlen() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awlock awlock() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awprot awprot() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awqos awqos() clocked_by (saxiclk) reset_by(saxireset);
      method awready(m_axi_awready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_awready);
      method m_axi_awsize awsize() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_awvalid awvalid() clocked_by (saxiclk) reset_by(saxireset);
      method bid(m_axi_bid) enable((*inhigh*) EN_m_axi_bid);
      method m_axi_bready bready() clocked_by (saxiclk) reset_by(saxireset);
      method bresp(m_axi_bresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_bresp);
      method bvalid(m_axi_bvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_bvalid);
      method rdata(m_axi_rdata)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rdata);
      method rid(m_axi_rid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rid);
      method rlast(m_axi_rlast)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rlast);
      method m_axi_rready rready() clocked_by (saxiclk) reset_by(saxireset);
      method rresp(m_axi_rresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rresp);
      method rvalid(m_axi_rvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_rvalid);
      method m_axi_wdata wdata() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_wid wid() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_wlast wlast() clocked_by (saxiclk) reset_by(saxireset);
      method wready(m_axi_wready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_m_axi_wready);
      method m_axi_wstrb wstrb() clocked_by (saxiclk) reset_by(saxireset);
      method m_axi_wvalid wvalid() clocked_by (saxiclk) reset_by(saxireset);
   endinterface

   interface ParMaxiGp maxi;
      method araddr(s_axi_araddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_araddr);
      method arburst(s_axi_arburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arburst);
      method arcache(s_axi_arcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arcache);
      method s_axi_aresetn aresetn() clocked_by(maxiclk) reset_by(maxireset);
      method arid(s_axi_arid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arid);
      method arlen(s_axi_arlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arlen);
      method arlock(s_axi_arlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arlock);
      method arprot(s_axi_arprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arprot);
      method arqos(s_axi_arqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arqos);
      method s_axi_arready arready() clocked_by(maxiclk) reset_by(maxireset);
      method arsize(s_axi_arsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arsize);
      method arvalid(s_axi_arvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_arvalid);
      method awaddr(s_axi_awaddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awaddr);
      method awburst(s_axi_awburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awburst);
      method awcache(s_axi_awcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awcache);
      method awid(s_axi_awid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awid);
      method awlen(s_axi_awlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awlen);
      method awlock(s_axi_awlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awlock);
      method awprot(s_axi_awprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awprot);
      method awqos(s_axi_awqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awqos);
      method s_axi_awready awready() clocked_by(maxiclk) reset_by(maxireset);
      method awsize(s_axi_awsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awsize);
      method awvalid(s_axi_awvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_awvalid);
      method s_axi_bid bid() clocked_by(maxiclk) reset_by(maxireset);
      method bready(s_axi_bready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_bready);
      method s_axi_bresp bresp() clocked_by(maxiclk) reset_by(maxireset);
      method s_axi_bvalid bvalid() clocked_by(maxiclk) reset_by(maxireset);
      method s_axi_rdata rdata() clocked_by(maxiclk) reset_by(maxireset);
      method s_axi_rlast rlast() clocked_by(maxiclk) reset_by(maxireset);
      method rready(s_axi_rready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_rready);
      method s_axi_rresp rresp() clocked_by(maxiclk) reset_by(maxireset);
      method s_axi_rvalid rvalid() clocked_by(maxiclk) reset_by(maxireset);
      method wdata(s_axi_wdata) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wdata);
      method wid(s_axi_wid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wid);
      method wlast(s_axi_wlast) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wlast);
      method s_axi_wready wready() clocked_by(maxiclk) reset_by(maxireset);
      method wstrb(s_axi_wstrb) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wstrb);
      method wvalid(s_axi_wvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_s_axi_wvalid);
      method s_axi_rid rid() clocked_by(maxiclk) reset_by(maxireset);
   endinterface

schedule (
   misc.csysack, misc.cactive, misc.reset_chip, misc.reset_fpga, tx.data_p, tx.data_n,
   tx.frame_p, tx.frame_n, tx.lclk_p, tx.lclk_n, rx.wr_wait_p,
   rx.wr_wait_n, rx.rd_wait_p, rx.rd_wait_n, misc.cclk_p,
   misc.cclk_n, maxi.awid, maxi.awaddr, maxi.awlen, maxi.awsize,
   maxi.awburst, maxi.awlock, maxi.awcache, maxi.awprot,
   maxi.awvalid, saxi.awready, maxi.wid, maxi.wdata, maxi.wstrb,
   maxi.wlast, maxi.wvalid, saxi.wready, maxi.bready, saxi.bid,
   saxi.bresp, saxi.bvalid, maxi.arid, maxi.araddr, maxi.arlen,
   maxi.arsize, maxi.arburst, maxi.arlock, maxi.arcache,
   maxi.arprot, maxi.arvalid, saxi.arready, maxi.rready,
   saxi.rid, saxi.rdata, saxi.rresp, saxi.rlast, saxi.rvalid,
   maxi.awqos, maxi.arqos,
   // Inputs
   // clkin_100, saxi.aclk, maxi.aclk, reset,
   saxi.aresetn,
   maxi.aresetn, misc.csysreq, rx.data_p, rx.data_n, rx.frame_p,
   rx.frame_n, rx.lclk_p, rx.lclk_n, tx.wr_wait_p, tx.wr_wait_n,
   tx.rd_wait_p, tx.rd_wait_n, maxi.awready, saxi.awid,
   saxi.awaddr, saxi.awlen, saxi.awsize, saxi.awburst,
   saxi.awlock, saxi.awcache, saxi.awprot, saxi.awvalid,
   maxi.wready, saxi.wid, saxi.wdata, saxi.wstrb, saxi.wlast,
   saxi.wvalid, maxi.bid, maxi.bresp, maxi.bvalid, saxi.bready,
   maxi.arready, saxi.arid, saxi.araddr, saxi.arlen, saxi.arsize,
   saxi.arburst, saxi.arlock, saxi.arcache, saxi.arprot,
   saxi.arvalid, maxi.rid, maxi.rdata, maxi.rresp, maxi.rlast,
   maxi.rvalid, saxi.rready, saxi.awqos, saxi.arqos
) CF (
   misc.csysack, misc.cactive, misc.reset_chip, misc.reset_fpga, tx.data_p, tx.data_n,
   tx.frame_p, tx.frame_n, tx.lclk_p, tx.lclk_n, rx.wr_wait_p,
   rx.wr_wait_n, rx.rd_wait_p, rx.rd_wait_n, misc.cclk_p,
   misc.cclk_n, maxi.awid, maxi.awaddr, maxi.awlen, maxi.awsize,
   maxi.awburst, maxi.awlock, maxi.awcache, maxi.awprot,
   maxi.awvalid, saxi.awready, maxi.wid, maxi.wdata, maxi.wstrb,
   maxi.wlast, maxi.wvalid, saxi.wready, maxi.bready, saxi.bid,
   saxi.bresp, saxi.bvalid, maxi.arid, maxi.araddr, maxi.arlen,
   maxi.arsize, maxi.arburst, maxi.arlock, maxi.arcache,
   maxi.arprot, maxi.arvalid, saxi.arready, maxi.rready,
   saxi.rid, saxi.rdata, saxi.rresp, saxi.rlast, saxi.rvalid,
   maxi.awqos, maxi.arqos,
   // Inputs
   // clkin_100, saxi.aclk, maxi.aclk, reset,
   saxi.aresetn,
   maxi.aresetn, misc.csysreq, rx.data_p, rx.data_n, rx.frame_p,
   rx.frame_n, rx.lclk_p, rx.lclk_n, tx.wr_wait_p, tx.wr_wait_n,
   tx.rd_wait_p, tx.rd_wait_n, maxi.awready, saxi.awid,
   saxi.awaddr, saxi.awlen, saxi.awsize, saxi.awburst,
   saxi.awlock, saxi.awcache, saxi.awprot, saxi.awvalid,
   maxi.wready, saxi.wid, saxi.wdata, saxi.wstrb, saxi.wlast,
   saxi.wvalid, maxi.bid, maxi.bresp, maxi.bvalid, saxi.bready,
   maxi.arready, saxi.arid, saxi.araddr, saxi.arlen, saxi.arsize,
   saxi.arburst, saxi.arlock, saxi.arcache, saxi.arprot,
   saxi.arvalid, maxi.rid, maxi.rdata, maxi.rresp, maxi.rlast,
   maxi.rvalid, saxi.rready, saxi.awqos, saxi.arqos

   );

endmodule


added timestamp to traceData() method

added timestamp to traceData() method

// Copyright (c) 2016 Connectal Project

// 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 ConnectalConfig::*;
`include "ConnectalProjectConfig.bsv"

typedef `PcieDataBusWidth PcieDataBusWidth;

typedef enum { DMA_RX, DMA_TX, DMA_SG } DmaChannel deriving (Bits,Eq);

interface MemServerPortalRequest;
   method Action read(Bit#(32) addr);
   method Action write(Bit#(32) addr, Bit#(DataBusWidth) data);
endinterface

interface MemServerPortalIndication;
   method Action readDone(Bit#(DataBusWidth) data);
   method Action writeDone();
endinterface

interface NvmeRequest;
   method Action read32(Bit#(32) addr);
   method Action write32(Bit#(32) addr, Bit#(32) data);
   method Action read(Bit#(32) addr);
   method Action write(Bit#(32) addr, Bit#(DataBusWidth) data);
   method Action readCtl(Bit#(32) addr);
   method Action writeCtl(Bit#(32) addr, Bit#(DataBusWidth) data);
   method Action status();
   method Action trace(Bool enabled);
   // FIXME: move to new portal
   method Action setSearchString(Bit#(32) needleSglId, Bit#(32) mpNextSglId, Bit#(32) needleLen);
   method Action startSearch(Bit#(32) searchLen);
   method Action startTransfer(Bit#(8) opcode, Bit#(8) flags, Bit#(16) requestId, Bit#(64) startBlock, Bit#(32) numBlocks, Bit#(32) dsm);
endinterface

interface NvmeIndication;
   method Action transferCompleted(Bit#(16) requestId, Bit#(64) sc, Bit#(32) cycles);
   method Action readDone(Bit#(DataBusWidth) data);
   method Action writeDone();
   method Action status(Bit#(1) mmcm_lock, Bit#(32) dataCounter);
   method Action strstrLoc(Bit#(32) loc);
   method Action setupComplete();
endinterface

interface NvmeTrace;
   method Action traceDmaRequest(DmaChannel channel, Bool write, Bit#(16) objId, Bit#(64) offset, Bit#(16) burstLen, Bit#(8) tag, Bit#(32) timestamp);
   method Action traceDmaData(DmaChannel channel, Bool write, Vector#(TDiv#(PcieDataBusWidth,32),Bit#(32)) data, Bool last, Bit#(8) tag, Bit#(32) timestamp);
   method Action traceDmaDone(DmaChannel channel, Bit#(8) tag, Bit#(32) timestamp);
   method Action traceData(Vector#(TDiv#(PcieDataBusWidth,32),Bit#(32)) data, Bool last, Bit#(8) tag, Bit#(32) timestamp);
endinterface

// Copyright (c) 2016 Connectal Project

// 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 ConnectalConfig::*;
`include "ConnectalProjectConfig.bsv"

typedef `PcieDataBusWidth PcieDataBusWidth;

typedef enum { DMA_RX, DMA_TX, DMA_SG } DmaChannel deriving (Bits,Eq);

interface MemServerPortalRequest;
   method Action read(Bit#(32) addr);
   method Action write(Bit#(32) addr, Bit#(DataBusWidth) data);
endinterface

interface MemServerPortalIndication;
   method Action readDone(Bit#(DataBusWidth) data);
   method Action writeDone();
endinterface

interface NvmeRequest;
   method Action read32(Bit#(32) addr);
   method Action write32(Bit#(32) addr, Bit#(32) data);
   method Action read(Bit#(32) addr);
   method Action write(Bit#(32) addr, Bit#(DataBusWidth) data);
   method Action readCtl(Bit#(32) addr);
   method Action writeCtl(Bit#(32) addr, Bit#(DataBusWidth) data);
   method Action status();
   method Action trace(Bool enabled);
   // FIXME: move to new portal
   method Action setSearchString(Bit#(32) needleSglId, Bit#(32) mpNextSglId, Bit#(32) needleLen);
   method Action startSearch(Bit#(32) searchLen);
   method Action startTransfer(Bit#(8) opcode, Bit#(8) flags, Bit#(16) requestId, Bit#(64) startBlock, Bit#(32) numBlocks, Bit#(32) dsm);
endinterface

interface NvmeIndication;
   method Action transferCompleted(Bit#(16) requestId, Bit#(64) sc, Bit#(32) cycles);
   method Action readDone(Bit#(DataBusWidth) data);
   method Action writeDone();
   method Action status(Bit#(1) mmcm_lock, Bit#(32) dataCounter);
   method Action strstrLoc(Bit#(32) loc);
   method Action setupComplete();
endinterface

interface NvmeTrace;
   method Action traceDmaRequest(DmaChannel channel, Bool write, Bit#(16) objId, Bit#(64) offset, Bit#(16) burstLen, Bit#(8) tag, Bit#(32) timestamp);
   method Action traceDmaData(DmaChannel channel, Bool write, Vector#(TDiv#(PcieDataBusWidth,32),Bit#(32)) data, Bool last, Bit#(8) tag, Bit#(32) timestamp);
   method Action traceDmaDone(DmaChannel channel, Bit#(8) tag, Bit#(32) timestamp);
   method Action traceData(Vector#(TDiv#(PcieDataBusWidth,32),Bit#(32)) data, Bool last, Bit#(8) tag);
endinterface