connected ready and valid bits in PS7

connected ready and valid bits in PS7

// 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 Clocks::*;
import DefaultValue::*;
import XilinxCells::*;
import GetPut::*;
import Vector::*;
import PPS7::*;

typedef struct {
    Bit#(32)                  addr;
    Bit#(2)                   burst;
    Bit#(4)                   cache;
    Bit#(id_width)            id;
    Bit#(4)                   len;
    Bit#(2)                   lock;
    Bit#(3)                   prot;
    Bit#(4)                   qos;
    Bit#(3)                   size;
} AxiREQ#(numeric type id_width);
typedef struct {
    Bit#(id_width)            id;
    Bit#(2)                   resp;
} AxiRESP#(numeric type id_width);
typedef struct {
    Bit#(data_width)          data;
    Bit#(1)                   last;
} AxiDATA#(numeric type data_width);
typedef struct {
    Bit#(id_width)            wid;
    AxiDATA#(data_width)      wd;
    Bit#(TDiv#(data_width, 8))wstrb;
} AxiWrite#(numeric type data_width, numeric type id_width);
typedef struct {
    AxiRESP#(id_width)        r;
    AxiDATA#(data_width)      rd;
} AxiRead#(numeric type data_width, numeric type id_width);

interface AxiMasterCommon#(numeric type data_width, numeric type id_width);
    method Action             aclk(Bit#(1) v); // common
    method Bit#(1)            aresetn();      // common

    method Bit#(1)            arvalid();
    interface Get#(AxiREQ#(id_width)) req_ar;
    method Action             arready(Bit#(1) v);

    method Bit#(1)            awvalid();
    interface Get#(AxiREQ#(id_width)) req_aw;
    method Action             awready(Bit#(1) v);

    method Action             rvalid(Bit#(1) v);
    interface Put#(AxiRead#(data_width, id_width)) resp_read;
    method Bit#(1)            rready();

    method Bit#(1)            wvalid();
    interface Get#(AxiWrite#(data_width, id_width)) resp_write;
    method Action             wready(Bit#(1) v);

    method Action             bvalid(Bit#(1) v);
    interface Put#(AxiRESP#(id_width)) resp_b;
    method Bit#(1)            bready();
endinterface

interface AxiSlaveCommon#(numeric type data_width, numeric type id_width);
    method Action             aclk(Bit#(1) v); // common
    method Bit#(1)            aresetn();      // common

    method Action             arvalid(Bit#(1) v);
    interface Put#(AxiREQ#(id_width)) req_ar;
    method Bit#(1)            arready();

    method Action             awvalid(Bit#(1) v);
    interface Put#(AxiREQ#(id_width)) req_aw;
    method Bit#(1)            awready();

    method Action             wvalid(Bit#(1) v);
    interface Put#(AxiWrite#(data_width, id_width)) resp_write;
    method Bit#(1)            wready();

    method Bit#(1)            rvalid();
    interface Get#(AxiRead#(data_width, id_width)) resp_read;
    method Action             rready(Bit#(1) v);

    method Bit#(1)            bvalid();
    interface Get#(AxiRESP#(id_width)) resp_b;
    method Action             bready(Bit#(1) v);
endinterface

interface AxiSlaveHighSpeed#(numeric type data_width, numeric type id_width);
    interface AxiSlaveCommon#(data_width, id_width) axi;
    method Bit#(3)            racount();
    method Bit#(8)            rcount();
    method Action             rdissuecap1_en(Bit#(1) v);
    method Bit#(6)            wacount();
    method Bit#(8)            wcount();
    method Action             wrissuecap1_en(Bit#(1) v);
endinterface

interface AxiMasterWires;
   interface Wire#(Bit#(1)) arready;
   interface Wire#(Bit#(1)) awready;
   interface Wire#(Bit#(1)) rvalid;
   interface Wire#(Bit#(1)) wready;
   interface Wire#(Bit#(1)) bvalid;
endinterface

interface AxiSlaveWires;
   interface Wire#(Bit#(1)) arvalid;
   interface Wire#(Bit#(1)) awvalid;
   interface Wire#(Bit#(1)) rready;
   interface Wire#(Bit#(1)) wvalid;
   interface Wire#(Bit#(1)) bready;
endinterface

module mkAxiMasterWires(AxiMasterWires);
   Vector#(5, Wire#(Bit#(1))) wires <- replicateM(mkDWire(0));
   interface Wire arready = wires[0];
   interface Wire awready = wires[1];
   interface Wire rvalid = wires[2];
   interface Wire wready = wires[3];
   interface Wire bvalid = wires[4];
endmodule

module mkAxiSlaveWires(AxiSlaveWires);
   Vector#(5, Wire#(Bit#(1))) wires <- replicateM(mkDWire(0));
   interface Wire arready = wires[0];
   interface Wire awready = wires[1];
   interface Wire rvalid = wires[2];
   interface Wire wready = wires[3];
   interface Wire bvalid = wires[4];
endmodule

(* always_ready, always_enabled *)
interface Bidir#(numeric type data_width);
    method Action             i(Bit#(data_width) v);
    method Bit#(data_width)   o();
    method Bit#(data_width)   t();
endinterface

interface PS7#(numeric type c_dm_width, numeric type c_dq_width, numeric type c_dqs_width, numeric type data_width, numeric type gpio_width, numeric type id_width, numeric type mio_width);
    interface Vector#(2, Pps7Can#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     can;
    interface Vector#(2, Pps7Core#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     core;
    interface Pps7Ddr#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     ddr;
    interface Vector#(4, Pps7Dma#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     dma;
    interface Vector#(2, Pps7Enet#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     enet;
    interface Pps7Event#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     event_;
    interface Pps7Fclk#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     fclk;
    interface Vector#(4, Pps7Fclk_clktrig#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     fclk_clktrig;
    interface Vector#(4, Pps7Fclk_reset#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     fclk_reset;
    interface Pps7Fpga#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     fpga;
    interface Pps7Gpio#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     gpio;
    interface Pps7Ftmd#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     ftmd;
    interface Pps7Ftmt#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     ftmt;
    interface Vector#(2, Pps7I2c#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     i2c;
    interface Pps7Irq#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     irq;
    interface Pps7Pjtag#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     pjtag;
    interface Pps7Ps#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     ps;
    interface Vector#(2, Pps7Sdio#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     sdio;
    interface Vector#(2, Pps7Spi#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     spi;
    interface Pps7Sram#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     sram;
    interface Pps7Trace#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     trace;
    interface Vector#(2, Pps7Ttc#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     ttc;
    interface Vector#(2, Pps7Uart#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     uart;
    interface Vector#(2, Pps7Usb#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     usb;
    interface Pps7Wdt#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     wdt;

    //interface Vector#(2, Pps7M_axi_gp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     m_axi_gp;
    //interface Pps7S_axi_acp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     s_axi_acp;
    //interface Vector#(2, Pps7S_axi_gp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     s_axi_gp;
    //interface Vector#(4, Pps7S_axi_hp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     s_axi_hp;
    interface Vector#(2, AxiMasterCommon#(32, id_width)) m_axi_gp;
    interface AxiSlaveCommon#(32, id_width) s_axi_acp;
    interface Vector#(2, AxiSlaveCommon#(32, id_width)) s_axi_gp;
    interface Vector#(4, AxiSlaveHighSpeed#(data_width, id_width)) s_axi_hp;
endinterface

module mkPS7#(int c_dm_width, int c_dq_width, int c_dqs_width, int data_width, int gpio_width, int id_width, int mio_width)
            (PS7#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width));
    PPS7#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)foo <-
        mkPPS7(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width);
    Vector#(2, Pps7Can#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vcan;
    Vector#(2, Pps7Core#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vcore;
    Vector#(4, Pps7Dma#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vdma;
    Vector#(2, Pps7Enet#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     venet;
    Vector#(4, Pps7Fclk_clktrig#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vfclk_clktrig;
    Vector#(4, Pps7Fclk_reset#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vfclk_reset;
    Vector#(2, Pps7I2c#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vi2c;
    Vector#(2, Pps7M_axi_gp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vm_axi_gp;
    Vector#(2, Pps7Sdio#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vsdio;
    Vector#(2, Pps7Spi#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vspi;
    Vector#(2, Pps7S_axi_gp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vs_axi_gp;
    Vector#(4, Pps7S_axi_hp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vs_axi_hp;
    Vector#(2, Pps7Ttc#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vttc;
    Vector#(2, Pps7Uart#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vuart;
    Vector#(2, Pps7Usb#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vusb;
    Vector#(2, AxiMasterCommon#(32, id_width)) vtopm_axi_gp;
    Vector#(2, AxiMasterWires) vtopmw_axi_gp <- replicateM(mkAxiMasterWires());
    Vector#(2, AxiSlaveCommon#(32, id_width)) vtops_axi_gp;
    Vector#(2, AxiSlaveWires) vtopsw_axi_gp <- replicateM(mkAxiSlaveWires());
    Vector#(4, AxiSlaveHighSpeed#(data_width, id_width)) vtops_axi_hp;
    Vector#(2, AxiSlaveWires) vtopsw_axi_hp <- replicateM(mkAxiSlaveWires());

    vcan[0] = foo.can0;
    vcan[1] = foo.can1;
    vcore[0] = foo.core0;
    vcore[1] = foo.core1;
    vdma[0] = foo.dma0;
    vdma[1] = foo.dma1;
    vdma[2] = foo.dma2;
    vdma[3] = foo.dma3;
    venet[0] = foo.enet0;
    venet[1] = foo.enet1;
    vfclk_clktrig[0] = foo.fclk_clktrig0;
    vfclk_clktrig[1] = foo.fclk_clktrig1;
    vfclk_clktrig[2] = foo.fclk_clktrig2;
    vfclk_clktrig[3] = foo.fclk_clktrig3;
    vfclk_reset[0] = foo.fclk_reset0;
    vfclk_reset[1] = foo.fclk_reset1;
    vfclk_reset[2] = foo.fclk_reset2;
    vfclk_reset[3] = foo.fclk_reset3;
    vi2c[0] = foo.i2c0;
    vi2c[1] = foo.i2c1;
    vm_axi_gp[0] = foo.m_axi_gp0;
    vm_axi_gp[1] = foo.m_axi_gp1;
    vsdio[0] = foo.sdio0;
    vsdio[1] = foo.sdio1;
    vspi[0] = foo.spi0;
    vspi[1] = foo.spi1;
    vs_axi_gp[0] = foo.s_axi_gp0;
    vs_axi_gp[1] = foo.s_axi_gp1;
    vs_axi_hp[0] = foo.s_axi_hp0;
    vs_axi_hp[1] = foo.s_axi_hp1;
    vs_axi_hp[2] = foo.s_axi_hp2;
    vs_axi_hp[3] = foo.s_axi_hp3;
    vttc[0] = foo.ttc0;
    vttc[1] = foo.ttc1;
    vuart[0] = foo.uart0;
    vuart[1] = foo.uart1;
    vusb[0] = foo.usb0;
    vusb[1] = foo.usb1;
    for (Integer i = 0; i < 2; i = i + 1)
       rule axi_master_handshake;
	    vm_axi_gp[i].arready(vtopmw_axi_gp[i].arready);
	    vm_axi_gp[i].awready(vtopmw_axi_gp[i].awready);
            vm_axi_gp[i].rvalid(vtopmw_axi_gp[i].rvalid);
	    vm_axi_gp[i].wready(vtopmw_axi_gp[i].wready);
            vm_axi_gp[i].bvalid(vtopmw_axi_gp[i].bvalid);
       endrule
    for (Integer i = 0; i < 2; i = i + 1)
        vtopm_axi_gp[i] = interface AxiMasterCommon#(32, id_width);
            interface Get req_ar;
                 method ActionValue#(AxiREQ#(id_width)) get() if (vm_axi_gp[i].arvalid());
                     AxiREQ#(id_width) v;
                     v.addr = vm_axi_gp[i].araddr();
                     v.burst = vm_axi_gp[i].arburst();
                     v.cache = vm_axi_gp[i].arcache();
                     v.id = vm_axi_gp[i].arid();
                     v.len = vm_axi_gp[i].arlen();
                     v.lock = vm_axi_gp[i].arlock();
                     v.prot = vm_axi_gp[i].arprot();
                     v.qos = vm_axi_gp[i].arqos();
                     v.size = vm_axi_gp[i].arsize();

		     vtopmw_axi_gp[i].arready <= 1;
                     return v;
                 endmethod
            endinterface
            interface Get req_aw;
                 method ActionValue#(AxiREQ#(id_width)) get() if (vm_axi_gp[i].awvalid());
                     AxiREQ#(id_width) v;
                     v.addr = vm_axi_gp[i].awaddr();
                     v.burst = vm_axi_gp[i].awburst();
                     v.cache = vm_axi_gp[i].awcache();
                     v.id = vm_axi_gp[i].awid();
                     v.len = vm_axi_gp[i].awlen();
                     v.lock = vm_axi_gp[i].awlock();
                     v.prot = vm_axi_gp[i].awprot();
                     v.qos = vm_axi_gp[i].awqos();
                     v.size = vm_axi_gp[i].awsize();

	             vtopmw_axi_gp[i].awready <= 1;
                     return v;
                endmethod
            endinterface
            interface Put resp_read;
                method Action put(AxiRead#(32, id_width) v) if (vm_axi_gp[i].rready());
                    vm_axi_gp[i].rid(v.r.id);
                    vm_axi_gp[i].rresp(v.r.resp);
                    vm_axi_gp[i].rdata(v.rd.data);
                    vm_axi_gp[i].rlast(v.rd.last);

	            vtopmw_axi_gp[i].rvalid <= 1;
                endmethod
            endinterface
            interface Get resp_write;
                 method ActionValue#(AxiWrite#(32, id_width)) get() if (vm_axi_gp[i].wvalid());
                     AxiWrite#(32, id_width) v;
                     v.wid = vm_axi_gp[i].wid();
                     v.wstrb = vm_axi_gp[i].wstrb();
                     v.wd.data = vm_axi_gp[i].wdata();
                     v.wd.last = vm_axi_gp[i].wlast();

	             vtopmw_axi_gp[i].wready <= 1;
                     return v;
                endmethod
            endinterface
            interface Put resp_b;
                method Action put(AxiRESP#(id_width) v) if (vm_axi_gp[i].bready());
                    vm_axi_gp[i].bid(v.id);
                    vm_axi_gp[i].bresp(v.resp);

	            vtopmw_axi_gp[i].bvalid <= 1;
                endmethod
            endinterface
            method aclk = vm_axi_gp[i].aclk;
            method aresetn = vm_axi_gp[i].aresetn;
            endinterface;
    for (Integer i = 0; i < 2; i = i + 1)
       rule axi_master_handshake;
	    vs_axi_gp[i].arvalid(vtopsw_axi_gp[i].arvalid);
	    vs_axi_gp[i].awvalid(vtopsw_axi_gp[i].awvalid);
            vs_axi_gp[i].rready(vtopsw_axi_gp[i].rready);
	    vs_axi_gp[i].wvalid(vtopsw_axi_gp[i].wvalid);
            vs_axi_gp[i].bready(vtopsw_axi_gp[i].bready);
       endrule
    for (Integer i = 0; i < 2; i = i + 1)
        vtops_axi_gp[i] = interface AxiSlaveCommon#(32, id_width);
            interface Put req_ar;
                method Action put(AxiREQ#(id_width) v) if (vs_axi_gp[i].arready());
                    vs_axi_gp[i].araddr(v.addr);
                    vs_axi_gp[i].arburst(v.burst);
                    vs_axi_gp[i].arcache(v.cache);
                    vs_axi_gp[i].arid(v.id);
                    vs_axi_gp[i].arlen(v.len);
                    vs_axi_gp[i].arlock(v.lock);
                    vs_axi_gp[i].arprot(v.prot);
                    vs_axi_gp[i].arqos(v.qos);
                    vs_axi_gp[i].arsize(v.size);

	            vtopsw_axi_gp[i].arvalid <= 1;
                endmethod
            endinterface
            interface Put req_aw;
                method Action put(AxiREQ#(id_width) v) if (vs_axi_gp[i].awready());
                    vs_axi_gp[i].awaddr(v.addr);
                    vs_axi_gp[i].awburst(v.burst);
                    vs_axi_gp[i].awcache(v.cache);
                    vs_axi_gp[i].awid(v.id);
                    vs_axi_gp[i].awlen(v.len);
                    vs_axi_gp[i].awlock(v.lock);
                    vs_axi_gp[i].awprot(v.prot);
                    vs_axi_gp[i].awqos(v.qos);
                    vs_axi_gp[i].awsize(v.size);

	            vtopsw_axi_gp[i].awvalid() <= 1;
                endmethod
            endinterface
            interface Put resp_write;
                method Action put(AxiWrite#(32, id_width) v) if (vs_axi_gp[i].wready());
                    vs_axi_gp[i].wid(v.wid);
                    vs_axi_gp[i].wstrb(v.wstrb);
                    vs_axi_gp[i].wdata(v.wd.data);
                    vs_axi_gp[i].wlast(v.wd.last);

	            vtopsw_axi_gp.wvalid <= 1;
                endmethod
            endinterface
            interface Get resp_read;
                method ActionValue#(AxiRead#(32, id_width)) get() if (vs_axi_gp[i].rvalid());
                    AxiRead#(32, id_width) v;
                    v.r.id = vs_axi_gp[i].rid();
                    v.r.resp = vs_axi_gp[i].rresp();
                    v.rd.data = vs_axi_gp[i].rdata();
                    v.rd.last = vs_axi_gp[i].rlast();

	            vtopsw_axi_gp.rready <= 1;
                    return v;
                endmethod
            endinterface
            interface Get resp_b;
                method ActionValue#(AxiRESP#(id_width)) get() if (vs_axi_gp[i].bvalid());
                    AxiRESP#(id_width) v;
                    v.id = vs_axi_gp[i].bid();
                    v.resp = vs_axi_gp[i].bresp();

	            vtopsw_axi_gp.bready <= 1;
                    return v;
                endmethod
            endinterface
            method aclk = vs_axi_gp[i].aclk;
            method aresetn = vs_axi_gp[i].aresetn;
        endinterface;
    for (Integer i = 0; i < 2; i = i + 1)
       rule axi_master_handshake;
	    vs_axi_hp[i].arvalid(vtopsw_axi_hp[i].arvalid);
	    vs_axi_hp[i].awvalid(vtopsw_axi_hp[i].awvalid);
            vs_axi_hp[i].rready(vtopsw_axi_hp[i].rready);
	    vs_axi_hp[i].wvalid(vtopsw_axi_hp[i].wvalid);
            vs_axi_hp[i].bready(vtopsw_axi_hp[i].bready);
       endrule
    for (Integer i = 0; i < 4; i = i + 1)
        vtops_axi_hp[i] = interface AxiSlaveHighSpeed#(data_width, id_width);
            interface AxiSlaveCommon axi;
            interface Put req_ar;
                method Action put(AxiREQ#(id_width) v) if (vs_axi_hp[i].arready());
                    vs_axi_hp[i].araddr(v.addr);
                    vs_axi_hp[i].arburst(v.burst);
                    vs_axi_hp[i].arcache(v.cache);
                    vs_axi_hp[i].arid(v.id);
                    vs_axi_hp[i].arlen(v.len);
                    vs_axi_hp[i].arlock(v.lock);
                    vs_axi_hp[i].arprot(v.prot);
                    vs_axi_hp[i].arqos(v.qos);
                    vs_axi_hp[i].arsize(v.size);

		    vs_axi_hp[i].arvalid(1);
                endmethod
            endinterface
            interface Put req_aw;
                method Action put(AxiREQ#(id_width) v) if (vs_axi_hp[i].awready());
                    vs_axi_hp[i].awaddr(v.addr);
                    vs_axi_hp[i].awburst(v.burst);
                    vs_axi_hp[i].awcache(v.cache);
                    vs_axi_hp[i].awid(v.id);
                    vs_axi_hp[i].awlen(v.len);
                    vs_axi_hp[i].awlock(v.lock);
                    vs_axi_hp[i].awprot(v.prot);
                    vs_axi_hp[i].awqos(v.qos);
                    vs_axi_hp[i].awsize(v.size);

	            vs_axi_hp[i].awvalid(1);
                endmethod
            endinterface
            interface Put resp_write;
                method Action put(AxiWrite#(data_width, id_width) v) if (vs_axi_hp[i].wready());
                    vs_axi_hp[i].wid(v.wid);
                    vs_axi_hp[i].wstrb(v.wstrb);
                    vs_axi_hp[i].wdata(v.wd.data);
                    vs_axi_hp[i].wlast(v.wd.last);

	            vs_axi_hp[i].wvalid(1);
                endmethod
            endinterface
            interface Get resp_read;
                method ActionValue#(AxiRead#(data_width, id_width)) get() if (vs_axi_hp[i].rvalid());
                    AxiRead#(data_width, id_width) v;
                    v.r.id = vs_axi_hp[i].rid();
                    v.r.resp = vs_axi_hp[i].rresp();
                    v.rd.data = vs_axi_hp[i].rdata();
                    v.rd.last = vs_axi_hp[i].rlast();

	            vs_axi_hp[i].rready(1);
                    return v;
                endmethod
            endinterface
            interface Get resp_b;
                method ActionValue#(AxiRESP#(id_width)) get() if (vs_axi_hp[i].bvalid());
                    AxiRESP#(id_width) v;
                    v.id = vs_axi_hp[i].bid();
                    v.resp = vs_axi_hp[i].bresp();

		    vs_axi_hp[i].bready();
                    return v;
                endmethod
            endinterface
            method aclk = vs_axi_hp[i].aclk;
            method aresetn = vs_axi_hp[i].aresetn;
            endinterface
            method racount = vs_axi_hp[i].racount;
            method rcount = vs_axi_hp[i].rcount;
            method rdissuecap1_en = vs_axi_hp[i].rdissuecap1_en;
            method wacount = vs_axi_hp[i].wacount;
            method wcount = vs_axi_hp[i].wcount;
            method wrissuecap1_en = vs_axi_hp[i].wrissuecap1_en;
        endinterface;

    interface Pps7Can can = vcan;
    interface Pps7Core     core = vcore;
    interface Pps7Dma     dma = vdma;
    interface Pps7Enet     enet = venet;
    interface Pps7Fclk_clktrig    fclk_clktrig = vfclk_clktrig;
    interface Pps7Fclk_reset    fclk_reset = vfclk_reset;
    interface Pps7I2c    i2c = vi2c;
    interface Pps7Sdio    sdio = vsdio;
    interface Pps7Spi    spi = vspi;
    interface Pps7Ttc    ttc = vttc;
    interface Pps7Uart    uart = vuart;
    interface Pps7Usb    usb = vusb;

    interface Pps7Ddr     ddr = foo.ddr;
    interface Pps7Event     event_ = foo.event_;
    interface Pps7Fclk     fclk = foo.fclk;
    interface Pps7Fpga     fpga = foo.fpga;
    interface Pps7Gpio     gpio = foo.gpio;
    interface Pps7Ftmd     ftmd = foo.ftmd;
    interface Pps7Ftmt     ftmt = foo.ftmt;
    interface Pps7Irq     irq = foo.irq;
    interface Pps7Pjtag     pjtag = foo.pjtag;
    interface Pps7Ps     ps = foo.ps;
    interface Pps7Sram     sram = foo.sram;
    interface Pps7Trace     trace = foo.trace;
    interface Pps7Wdt     wdt = foo.wdt;
    interface AxiMasterCommon m_axi_gp = vtopm_axi_gp;
    interface AxiSlaveCommon s_axi_gp = vtops_axi_gp;
    interface AxiSlaveHighSpeed s_axi_hp = vtops_axi_hp;
    //interface AxiSlaveCommon s_axi_acp;
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.

import Clocks::*;
import DefaultValue::*;
import XilinxCells::*;
import GetPut::*;
import Vector::*;
import PPS7::*;

typedef struct {
    Bit#(32)                  addr;
    Bit#(2)                   burst;
    Bit#(4)                   cache;
    Bit#(id_width)            id;
    Bit#(4)                   len;
    Bit#(2)                   lock;
    Bit#(3)                   prot;
    Bit#(4)                   qos;
    Bit#(3)                   size;
} AxiREQ#(numeric type id_width);
typedef struct {
    Bit#(id_width)            id;
    Bit#(2)                   resp;
} AxiRESP#(numeric type id_width);
typedef struct {
    Bit#(data_width)          data;
    Bit#(1)                   last;
} AxiDATA#(numeric type data_width);
typedef struct {
    Bit#(id_width)            wid;
    AxiDATA#(data_width)      wd;
    Bit#(TDiv#(data_width, 8))wstrb;
} AxiWrite#(numeric type data_width, numeric type id_width);
typedef struct {
    AxiRESP#(id_width)        r;
    AxiDATA#(data_width)      rd;
} AxiRead#(numeric type data_width, numeric type id_width);

interface AxiMasterCommon#(numeric type data_width, numeric type id_width);
    method Action             aclk(Bit#(1) v); // common
    method Bit#(1)            aresetn();      // common

    method Bit#(1)            arvalid();
    interface Get#(AxiREQ#(id_width)) req_ar;
    method Action             arready(Bit#(1) v);

    method Bit#(1)            awvalid();
    interface Get#(AxiREQ#(id_width)) req_aw;
    method Action             awready(Bit#(1) v);

    method Action             rvalid(Bit#(1) v);
    interface Put#(AxiRead#(data_width, id_width)) resp_read;
    method Bit#(1)            rready();

    method Bit#(1)            wvalid();
    interface Get#(AxiWrite#(data_width, id_width)) resp_write;
    method Action             wready(Bit#(1) v);

    method Action             bvalid(Bit#(1) v);
    interface Put#(AxiRESP#(id_width)) resp_b;
    method Bit#(1)            bready();
endinterface

interface AxiSlaveCommon#(numeric type data_width, numeric type id_width);
    method Action             aclk(Bit#(1) v); // common
    method Bit#(1)            aresetn();      // common

    method Action             arvalid(Bit#(1) v);
    interface Put#(AxiREQ#(id_width)) req_ar;
    method Bit#(1)            arready();

    method Action             awvalid(Bit#(1) v);
    interface Put#(AxiREQ#(id_width)) req_aw;
    method Bit#(1)            awready();

    method Action             wvalid(Bit#(1) v);
    interface Put#(AxiWrite#(data_width, id_width)) resp_write;
    method Bit#(1)            wready();

    method Bit#(1)            rvalid();
    interface Get#(AxiRead#(data_width, id_width)) resp_read;
    method Action             rready(Bit#(1) v);

    method Bit#(1)            bvalid();
    interface Get#(AxiRESP#(id_width)) resp_b;
    method Action             bready(Bit#(1) v);
endinterface

interface AxiSlaveHighSpeed#(numeric type data_width, numeric type id_width);
    interface AxiSlaveCommon#(data_width, id_width) axi;
    method Bit#(3)            racount();
    method Bit#(8)            rcount();
    method Action             rdissuecap1_en(Bit#(1) v);
    method Bit#(6)            wacount();
    method Bit#(8)            wcount();
    method Action             wrissuecap1_en(Bit#(1) v);
endinterface

(* always_ready, always_enabled *)
interface Bidir#(numeric type data_width);
    method Action             i(Bit#(data_width) v);
    method Bit#(data_width)   o();
    method Bit#(data_width)   t();
endinterface

interface PS7#(numeric type c_dm_width, numeric type c_dq_width, numeric type c_dqs_width, numeric type data_width, numeric type gpio_width, numeric type id_width, numeric type mio_width);
    interface Vector#(2, Pps7Can#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     can;
    interface Vector#(2, Pps7Core#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     core;
    interface Pps7Ddr#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     ddr;
    interface Vector#(4, Pps7Dma#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     dma;
    interface Vector#(2, Pps7Enet#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     enet;
    interface Pps7Event#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     event_;
    interface Pps7Fclk#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     fclk;
    interface Vector#(4, Pps7Fclk_clktrig#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     fclk_clktrig;
    interface Vector#(4, Pps7Fclk_reset#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     fclk_reset;
    interface Pps7Fpga#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     fpga;
    interface Pps7Gpio#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     gpio;
    interface Pps7Ftmd#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     ftmd;
    interface Pps7Ftmt#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     ftmt;
    interface Vector#(2, Pps7I2c#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     i2c;
    interface Pps7Irq#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     irq;
    interface Pps7Pjtag#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     pjtag;
    interface Pps7Ps#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     ps;
    interface Vector#(2, Pps7Sdio#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     sdio;
    interface Vector#(2, Pps7Spi#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     spi;
    interface Pps7Sram#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     sram;
    interface Pps7Trace#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     trace;
    interface Vector#(2, Pps7Ttc#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     ttc;
    interface Vector#(2, Pps7Uart#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     uart;
    interface Vector#(2, Pps7Usb#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     usb;
    interface Pps7Wdt#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     wdt;

    //interface Vector#(2, Pps7M_axi_gp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     m_axi_gp;
    //interface Pps7S_axi_acp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)     s_axi_acp;
    //interface Vector#(2, Pps7S_axi_gp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     s_axi_gp;
    //interface Vector#(4, Pps7S_axi_hp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     s_axi_hp;
    interface Vector#(2, AxiMasterCommon#(32, id_width)) m_axi_gp;
    interface AxiSlaveCommon#(32, id_width) s_axi_acp;
    interface Vector#(2, AxiSlaveCommon#(32, id_width)) s_axi_gp;
    interface Vector#(4, AxiSlaveHighSpeed#(data_width, id_width)) s_axi_hp;
endinterface

module mkPS7#(int c_dm_width, int c_dq_width, int c_dqs_width, int data_width, int gpio_width, int id_width, int mio_width)
            (PS7#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width));
    PPS7#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width)foo <-
        mkPPS7(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width);
    Vector#(2, Pps7Can#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vcan;
    Vector#(2, Pps7Core#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vcore;
    Vector#(4, Pps7Dma#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vdma;
    Vector#(2, Pps7Enet#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     venet;
    Vector#(4, Pps7Fclk_clktrig#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vfclk_clktrig;
    Vector#(4, Pps7Fclk_reset#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vfclk_reset;
    Vector#(2, Pps7I2c#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vi2c;
    Vector#(2, Pps7M_axi_gp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vm_axi_gp;
    Vector#(2, Pps7Sdio#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vsdio;
    Vector#(2, Pps7Spi#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vspi;
    Vector#(2, Pps7S_axi_gp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vs_axi_gp;
    Vector#(4, Pps7S_axi_hp#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vs_axi_hp;
    Vector#(2, Pps7Ttc#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vttc;
    Vector#(2, Pps7Uart#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vuart;
    Vector#(2, Pps7Usb#(c_dm_width, c_dq_width, c_dqs_width, data_width, gpio_width, id_width, mio_width))     vusb;
    Vector#(2, AxiMasterCommon#(32, id_width)) vtopm_axi_gp;
    Vector#(2, AxiSlaveCommon#(32, id_width)) vtops_axi_gp;
    Vector#(4, AxiSlaveHighSpeed#(data_width, id_width)) vtops_axi_hp;

    vcan[0] = foo.can0;
    vcan[1] = foo.can1;
    vcore[0] = foo.core0;
    vcore[1] = foo.core1;
    vdma[0] = foo.dma0;
    vdma[1] = foo.dma1;
    vdma[2] = foo.dma2;
    vdma[3] = foo.dma3;
    venet[0] = foo.enet0;
    venet[1] = foo.enet1;
    vfclk_clktrig[0] = foo.fclk_clktrig0;
    vfclk_clktrig[1] = foo.fclk_clktrig1;
    vfclk_clktrig[2] = foo.fclk_clktrig2;
    vfclk_clktrig[3] = foo.fclk_clktrig3;
    vfclk_reset[0] = foo.fclk_reset0;
    vfclk_reset[1] = foo.fclk_reset1;
    vfclk_reset[2] = foo.fclk_reset2;
    vfclk_reset[3] = foo.fclk_reset3;
    vi2c[0] = foo.i2c0;
    vi2c[1] = foo.i2c1;
    vm_axi_gp[0] = foo.m_axi_gp0;
    vm_axi_gp[1] = foo.m_axi_gp1;
    vsdio[0] = foo.sdio0;
    vsdio[1] = foo.sdio1;
    vspi[0] = foo.spi0;
    vspi[1] = foo.spi1;
    vs_axi_gp[0] = foo.s_axi_gp0;
    vs_axi_gp[1] = foo.s_axi_gp1;
    vs_axi_hp[0] = foo.s_axi_hp0;
    vs_axi_hp[1] = foo.s_axi_hp1;
    vs_axi_hp[2] = foo.s_axi_hp2;
    vs_axi_hp[3] = foo.s_axi_hp3;
    vttc[0] = foo.ttc0;
    vttc[1] = foo.ttc1;
    vuart[0] = foo.uart0;
    vuart[1] = foo.uart1;
    vusb[0] = foo.usb0;
    vusb[1] = foo.usb1;
    for (Integer i = 0; i < 2; i = i + 1)
        vtopm_axi_gp[i] = interface AxiMasterCommon#(32, id_width);
            interface Get req_ar;
                 method ActionValue#(AxiREQ#(id_width)) get();
                     AxiREQ#(id_width) v;
                     v.addr = vm_axi_gp[i].araddr();
                     v.burst = vm_axi_gp[i].arburst();
                     v.cache = vm_axi_gp[i].arcache();
                     v.id = vm_axi_gp[i].arid();
                     v.len = vm_axi_gp[i].arlen();
                     v.lock = vm_axi_gp[i].arlock();
                     v.prot = vm_axi_gp[i].arprot();
                     v.qos = vm_axi_gp[i].arqos();
                     v.size = vm_axi_gp[i].arsize();
                     return v;
                 endmethod
            endinterface
            interface Get req_aw;
                 method ActionValue#(AxiREQ#(id_width)) get();
                     AxiREQ#(id_width) v;
                     v.addr = vm_axi_gp[i].awaddr();
                     v.burst = vm_axi_gp[i].awburst();
                     v.cache = vm_axi_gp[i].awcache();
                     v.id = vm_axi_gp[i].awid();
                     v.len = vm_axi_gp[i].awlen();
                     v.lock = vm_axi_gp[i].awlock();
                     v.prot = vm_axi_gp[i].awprot();
                     v.qos = vm_axi_gp[i].awqos();
                     v.size = vm_axi_gp[i].awsize();
                     return v;
                endmethod
            endinterface
            interface Put resp_read;
                method Action put(AxiRead#(32, id_width) v);
                    vm_axi_gp[i].rid(v.r.id);
                    vm_axi_gp[i].rresp(v.r.resp);
                    vm_axi_gp[i].rdata(v.rd.data);
                    vm_axi_gp[i].rlast(v.rd.last);
                endmethod
            endinterface
            interface Get resp_write;
                 method ActionValue#(AxiWrite#(32, id_width)) get();
                     AxiWrite#(32, id_width) v;
                     v.wid = vm_axi_gp[i].wid();
                     v.wstrb = vm_axi_gp[i].wstrb();
                     v.wd.data = vm_axi_gp[i].wdata();
                     v.wd.last = vm_axi_gp[i].wlast();
                     return v;
                endmethod
            endinterface
            interface Put resp_b;
                method Action put(AxiRESP#(id_width) v);
                    vm_axi_gp[i].bid(v.id);
                    vm_axi_gp[i].bresp(v.resp);
                endmethod
            endinterface
            method aclk = vm_axi_gp[i].aclk;
            method aresetn = vm_axi_gp[i].aresetn;
            method arvalid = vm_axi_gp[i].arvalid;
            method arready = vm_axi_gp[i].arready;
            method awvalid = vm_axi_gp[i].awvalid;
            method awready = vm_axi_gp[i].awready;
            method rvalid = vm_axi_gp[i].rvalid;
            method rready() = vm_axi_gp[i].rready;
            method wvalid() = vm_axi_gp[i].wvalid;
            method wready = vm_axi_gp[i].wready;
            method bvalid = vm_axi_gp[i].bvalid;
            method bready = vm_axi_gp[i].bready;
            endinterface;
    for (Integer i = 0; i < 2; i = i + 1)
        vtops_axi_gp[i] = interface AxiSlaveCommon#(32, id_width);
            interface Put req_ar;
                method Action put(AxiREQ#(id_width) v);
                    vs_axi_gp[i].araddr(v.addr);
                    vs_axi_gp[i].arburst(v.burst);
                    vs_axi_gp[i].arcache(v.cache);
                    vs_axi_gp[i].arid(v.id);
                    vs_axi_gp[i].arlen(v.len);
                    vs_axi_gp[i].arlock(v.lock);
                    vs_axi_gp[i].arprot(v.prot);
                    vs_axi_gp[i].arqos(v.qos);
                    vs_axi_gp[i].arsize(v.size);
                endmethod
            endinterface
            interface Put req_aw;
                method Action put(AxiREQ#(id_width) v);
                    vs_axi_gp[i].awaddr(v.addr);
                    vs_axi_gp[i].awburst(v.burst);
                    vs_axi_gp[i].awcache(v.cache);
                    vs_axi_gp[i].awid(v.id);
                    vs_axi_gp[i].awlen(v.len);
                    vs_axi_gp[i].awlock(v.lock);
                    vs_axi_gp[i].awprot(v.prot);
                    vs_axi_gp[i].awqos(v.qos);
                    vs_axi_gp[i].awsize(v.size);
                endmethod
            endinterface
            interface Put resp_write;
                method Action put(AxiWrite#(32, id_width) v);
                    vs_axi_gp[i].wid(v.wid);
                    vs_axi_gp[i].wstrb(v.wstrb);
                    vs_axi_gp[i].wdata(v.wd.data);
                    vs_axi_gp[i].wlast(v.wd.last);
                endmethod
            endinterface
            interface Get resp_read;
                method ActionValue#(AxiRead#(32, id_width)) get();
                    AxiRead#(32, id_width) v;
                    v.r.id = vs_axi_gp[i].rid();
                    v.r.resp = vs_axi_gp[i].rresp();
                    v.rd.data = vs_axi_gp[i].rdata();
                    v.rd.last = vs_axi_gp[i].rlast();
                    return v;
                endmethod
            endinterface
            interface Get resp_b;
                method ActionValue#(AxiRESP#(id_width)) get();
                    AxiRESP#(id_width) v;
                    v.id = vs_axi_gp[i].bid();
                    v.resp = vs_axi_gp[i].bresp();
                    return v;
                endmethod
            endinterface
            method aclk = vs_axi_gp[i].aclk;
            method aresetn = vs_axi_gp[i].aresetn;
            method arvalid = vs_axi_gp[i].arvalid;
            method arready = vs_axi_gp[i].arready;
            method awvalid = vs_axi_gp[i].awvalid;
            method awready = vs_axi_gp[i].awready;
            method rvalid = vs_axi_gp[i].rvalid;
            method rready() = vs_axi_gp[i].rready;
            method wvalid() = vs_axi_gp[i].wvalid;
            method wready = vs_axi_gp[i].wready;
            method bvalid = vs_axi_gp[i].bvalid;
            method bready = vs_axi_gp[i].bready;
        endinterface;
    for (Integer i = 0; i < 4; i = i + 1)
        vtops_axi_hp[i] = interface AxiSlaveHighSpeed#(data_width, id_width);
            interface AxiSlaveCommon axi;
            interface Put req_ar;
                method Action put(AxiREQ#(id_width) v);
                    vs_axi_hp[i].araddr(v.addr);
                    vs_axi_hp[i].arburst(v.burst);
                    vs_axi_hp[i].arcache(v.cache);
                    vs_axi_hp[i].arid(v.id);
                    vs_axi_hp[i].arlen(v.len);
                    vs_axi_hp[i].arlock(v.lock);
                    vs_axi_hp[i].arprot(v.prot);
                    vs_axi_hp[i].arqos(v.qos);
                    vs_axi_hp[i].arsize(v.size);
                endmethod
            endinterface
            interface Put req_aw;
                method Action put(AxiREQ#(id_width) v);
                    vs_axi_hp[i].awaddr(v.addr);
                    vs_axi_hp[i].awburst(v.burst);
                    vs_axi_hp[i].awcache(v.cache);
                    vs_axi_hp[i].awid(v.id);
                    vs_axi_hp[i].awlen(v.len);
                    vs_axi_hp[i].awlock(v.lock);
                    vs_axi_hp[i].awprot(v.prot);
                    vs_axi_hp[i].awqos(v.qos);
                    vs_axi_hp[i].awsize(v.size);
                endmethod
            endinterface
            interface Put resp_write;
                method Action put(AxiWrite#(data_width, id_width) v);
                    vs_axi_hp[i].wid(v.wid);
                    vs_axi_hp[i].wstrb(v.wstrb);
                    vs_axi_hp[i].wdata(v.wd.data);
                    vs_axi_hp[i].wlast(v.wd.last);
                endmethod
            endinterface
            interface Get resp_read;
                method ActionValue#(AxiRead#(data_width, id_width)) get();
                    AxiRead#(data_width, id_width) v;
                    v.r.id = vs_axi_hp[i].rid();
                    v.r.resp = vs_axi_hp[i].rresp();
                    v.rd.data = vs_axi_hp[i].rdata();
                    v.rd.last = vs_axi_hp[i].rlast();
                    return v;
                endmethod
            endinterface
            interface Get resp_b;
                method ActionValue#(AxiRESP#(id_width)) get();
                    AxiRESP#(id_width) v;
                    v.id = vs_axi_hp[i].bid();
                    v.resp = vs_axi_hp[i].bresp();
                    return v;
                endmethod
            endinterface
            method aclk = vs_axi_hp[i].aclk;
            method aresetn = vs_axi_hp[i].aresetn;
            method arvalid = vs_axi_hp[i].arvalid;
            method arready = vs_axi_hp[i].arready;
            method awvalid = vs_axi_hp[i].awvalid;
            method awready = vs_axi_hp[i].awready;
            method rvalid = vs_axi_hp[i].rvalid;
            method rready() = vs_axi_hp[i].rready;
            method wvalid() = vs_axi_hp[i].wvalid;
            method wready = vs_axi_hp[i].wready;
            method bvalid = vs_axi_hp[i].bvalid;
            method bready = vs_axi_hp[i].bready;
            endinterface
            method racount = vs_axi_hp[i].racount;
            method rcount = vs_axi_hp[i].rcount;
            method rdissuecap1_en = vs_axi_hp[i].rdissuecap1_en;
            method wacount = vs_axi_hp[i].wacount;
            method wcount = vs_axi_hp[i].wcount;
            method wrissuecap1_en = vs_axi_hp[i].wrissuecap1_en;
        endinterface;

    interface Pps7Can can = vcan;
    interface Pps7Core     core = vcore;
    interface Pps7Dma     dma = vdma;
    interface Pps7Enet     enet = venet;
    interface Pps7Fclk_clktrig    fclk_clktrig = vfclk_clktrig;
    interface Pps7Fclk_reset    fclk_reset = vfclk_reset;
    interface Pps7I2c    i2c = vi2c;
    interface Pps7Sdio    sdio = vsdio;
    interface Pps7Spi    spi = vspi;
    interface Pps7Ttc    ttc = vttc;
    interface Pps7Uart    uart = vuart;
    interface Pps7Usb    usb = vusb;

    interface Pps7Ddr     ddr = foo.ddr;
    interface Pps7Event     event_ = foo.event_;
    interface Pps7Fclk     fclk = foo.fclk;
    interface Pps7Fpga     fpga = foo.fpga;
    interface Pps7Gpio     gpio = foo.gpio;
    interface Pps7Ftmd     ftmd = foo.ftmd;
    interface Pps7Ftmt     ftmt = foo.ftmt;
    interface Pps7Irq     irq = foo.irq;
    interface Pps7Pjtag     pjtag = foo.pjtag;
    interface Pps7Ps     ps = foo.ps;
    interface Pps7Sram     sram = foo.sram;
    interface Pps7Trace     trace = foo.trace;
    interface Pps7Wdt     wdt = foo.wdt;
    interface AxiMasterCommon m_axi_gp = vtopm_axi_gp;
    interface AxiSlaveCommon s_axi_gp = vtops_axi_gp;
    interface AxiSlaveHighSpeed s_axi_hp = vtops_axi_hp;
    //interface AxiSlaveCommon s_axi_acp;
endmodule


connect store-and-forward with mac/phy

connect store-and-forward with mac/phy

// Copyright (c) 2016 Cornell University.

// 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.

package MemoryTest;

import FIFO::*;
import FIFOF::*;
import DefaultValue::*;
import Vector::*;
import BuildVector::*;
import GetPut::*;
import ClientServer::*;
import Connectable::*;
import Clocks::*;
import Gearbox::*;
import Pipe::*;

import MemServerIndication::*;
import MMUIndication::*;
import MemTypes::*;
import Ethernet::*;
import MemoryAPI::*;
import PacketBuffer::*;
import SharedBuff::*;
import StoreAndForward::*;

`ifndef SIMULATION
import AlteraMacWrap::*;
import EthMac::*;
import AlteraEthPhy::*;
import DE5Pins::*;
`else
import Sims::*;
`endif

interface MemoryTest;
   interface MemoryTestRequest request;
   interface `PinType pins;
endinterface

module mkMemoryTest#(MemoryTestIndication indication, ConnectalMemory::MemServerIndication memServerIndication, Malloc::MallocIndication mallocIndication)(MemoryTest);
   let verbose = False;

   Clock defaultClock <- exposeCurrentClock();
   Reset defaultReset <- exposeCurrentReset();

   Wire#(Bit#(1)) clk_644_wire <- mkDWire(0);
   Wire#(Bit#(1)) clk_50_wire <- mkDWire(0);

`ifndef SIMULATION
   De5Clocks clocks <- mkDe5Clocks(clk_50_wire, clk_644_wire);
`else
   SimClocks clocks <- mkSimClocks();
`endif

   Clock txClock = clocks.clock_156_25;
   Clock phyClock = clocks.clock_644_53;
   Clock mgmtClock = clocks.clock_50;
   Reset txReset <- mkSyncReset(2, defaultReset, txClock);
   Reset phyReset <- mkSyncReset(2, defaultReset, phyClock);
   Reset mgmtReset <- mkSyncReset(2, defaultReset, mgmtClock);

`ifndef SIMULATION
   // DE5 Pins
   De5Leds leds <- mkDe5Leds(defaultClock, txClock, mgmtClock, phyClock);
   De5SfpCtrl#(4) sfpctrl <- mkDe5SfpCtrl();
   De5Buttons#(4) buttons <- mkDe5Buttons(clocked_by mgmtClock, reset_by mgmtReset);

   EthPhyIfc phys <- mkAlteraEthPhy(defaultClock, phyClock, txClock, defaultReset);
   Clock rxClock = phys.rx_clkout;
   Reset rxReset <- mkSyncReset(2, defaultReset, rxClock);
   Vector#(4, EthMacIfc) mac <- replicateM(mkEthMac(defaultClock, txClock, rxClock, txReset));

   for (Integer i=0; i<4; i=i+1) begin
      mkConnection(mac[i].tx, phys.tx[i]);
      mkConnection(phys.rx[i], mac[i].rx);
   end
`endif

   PacketBuffer incoming_buff <- mkPacketBuffer();
   StoreAndFwdFromRingToMem ringToMem <- mkStoreAndFwdFromRingToMem();

   PacketBuffer outgoing_buff <- mkPacketBuffer();
   StoreAndFwdFromMemToRing memToRing <- mkStoreAndFwdFromMemToRing();

   SharedBuffer#(12, 128, 1) mem <- mkSharedBuffer(vec(memToRing.readClient), vec(ringToMem.writeClient), memServerIndication, mallocIndication);

   mkConnection(ringToMem.readClient, incoming_buff.readServer);
   mkConnection(ringToMem.mallocReq, mem.mallocReq);
   mkConnection(mem.mallocDone, ringToMem.mallocDone);

   mkConnection(memToRing.writeClient, outgoing_buff.writeServer);

   mkConnection(ringToMem.eventPktCommitted, memToRing.eventPktSend);

   StoreAndFwdFromRingToMac ringToMac <- mkStoreAndFwdFromRingToMac(txClock, txReset);

   mkConnection(ringToMac.readClient, outgoing_buff.readServer);

`ifndef SIMULATION
   mkConnection(ringToMac.macTx, mac[0].packet_tx);
`else
   rule drain_mac;
      let v <- ringToMac.macTx.get;
      if (verbose) $display("tx data %h", v);
   endrule
`endif

   MemoryAPI api <- mkMemoryAPI(indication, incoming_buff);

   interface request = api.request;
`ifndef SIMULATION
   interface `PinType pins;
      method Action osc_50(Bit#(1) b3d, Bit#(1) b4a, Bit#(1) b4d, Bit#(1) b7a, Bit#(1) b7d, Bit#(1) b8a, Bit#(1) b8d);
         clk_50_wire <= b4a;
      endmethod
      method serial_tx_data = phys.serial_tx;
      method serial_rx = phys.serial_rx;
      method Action sfp(Bit#(1) refclk);
         clk_644_wire <= refclk;
      endmethod
      interface i2c = clocks.i2c;
      interface led = leds.led_out;
      interface led_bracket = leds.led_out;
      interface sfpctrl = sfpctrl;
      interface buttons = buttons.pins;
      interface deleteme_unused_clock = defaultClock;
      interface deleteme_unused_clock2 = clocks.clock_50;
      interface deleteme_unused_clock3 = defaultClock;
      interface deleteme_unused_reset = defaultReset;
   endinterface
`endif
endmodule
endpackage

// Copyright (c) 2016 Cornell University.

// 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.

package MemoryTest;

import FIFO::*;
import FIFOF::*;
import DefaultValue::*;
import Vector::*;
import BuildVector::*;
import GetPut::*;
import ClientServer::*;
import Connectable::*;
import Clocks::*;
import Gearbox::*;
import Pipe::*;

import MemServerIndication::*;
import MMUIndication::*;
import MemTypes::*;
import Ethernet::*;
import MemoryAPI::*;
import PacketBuffer::*;
import SharedBuff::*;
import StoreAndForward::*;

`ifndef SIMULATION
import AlteraMacWrap::*;
import EthMac::*;
import AlteraEthPhy::*;
import DE5Pins::*;
`endif

interface MemoryTest;
   interface MemoryTestRequest request;
   interface `PinType pins;
endinterface

module mkMemoryTest#(MemoryTestIndication indication, ConnectalMemory::MemServerIndication memServerIndication, Malloc::MallocIndication mallocIndication)(MemoryTest);
   Clock defaultClock <- exposeCurrentClock();
   Reset defaultReset <- exposeCurrentReset();

   Wire#(Bit#(1)) clk_644_wire <- mkDWire(0);
   Wire#(Bit#(1)) clk_50_wire <- mkDWire(0);

`ifndef SIMULATION
   De5Clocks clocks <- mkDe5Clocks(clk_50_wire, clk_644_wire);
`endif

`ifndef SIMULATION
   Clock txClock = clocks.clock_156_25;
   Clock phyClock = clocks.clock_644_53;
   Clock mgmtClock = clocks.clock_50;
   Reset txReset <- mkSyncReset(2, defaultReset, txClock);
   Reset phyReset <- mkSyncReset(2, defaultReset, phyClock);
   Reset mgmtReset <- mkSyncReset(2, defaultReset, mgmtClock);

   // DE5 Pins
   De5Leds leds <- mkDe5Leds(defaultClock, txClock, mgmtClock, phyClock);
   De5SfpCtrl#(4) sfpctrl <- mkDe5SfpCtrl();
   De5Buttons#(4) buttons <- mkDe5Buttons(clocked_by mgmtClock, reset_by mgmtReset);

   EthPhyIfc phys <- mkAlteraEthPhy(defaultClock, phyClock, txClock, defaultReset);
   Clock rxClock = phys.rx_clkout;
   Reset rxReset <- mkSyncReset(2, defaultReset, rxClock);
   Vector#(4, EthMacIfc) mac <- replicateM(mkEthMac(defaultClock, txClock, rxClock, txReset));
`endif

   PacketBuffer incoming_buff <- mkPacketBuffer();
   StoreAndFwdFromRingToMem ringToMem <- mkStoreAndFwdFromRingToMem();

   PacketBuffer outgoing_buff <- mkPacketBuffer();
   StoreAndFwdFromMemToRing memToRing <- mkStoreAndFwdFromMemToRing();

   SharedBuffer#(12, 128, 1) mem <- mkSharedBuffer(vec(memToRing.readClient), vec(ringToMem.writeClient), memServerIndication, mallocIndication);

   mkConnection(ringToMem.readClient, incoming_buff.readServer);
   mkConnection(ringToMem.mallocReq, mem.mallocReq);
   mkConnection(mem.mallocDone, ringToMem.mallocDone);

   mkConnection(memToRing.writeClient, outgoing_buff.writeServer);

   mkConnection(ringToMem.eventPktCommitted, memToRing.eventPktSend);

   MemoryAPI api <- mkMemoryAPI(indication, incoming_buff);

   interface request = api.request;
`ifndef SIMULATION
   interface `PinType pins;
      method Action osc_50(Bit#(1) b3d, Bit#(1) b4a, Bit#(1) b4d, Bit#(1) b7a, Bit#(1) b7d, Bit#(1) b8a, Bit#(1) b8d);
         clk_50_wire <= b4a;
      endmethod
      method serial_tx_data = phys.serial_tx;
      method serial_rx = phys.serial_rx;
      method Action sfp(Bit#(1) refclk);
         clk_644_wire <= refclk;
      endmethod
      interface i2c = clocks.i2c;
      interface led = leds.led_out;
      interface led_bracket = leds.led_out;
      interface sfpctrl = sfpctrl;
      interface buttons = buttons.pins;
      interface deleteme_unused_clock = defaultClock;
      interface deleteme_unused_clock2 = clocks.clock_50;
      interface deleteme_unused_clock3 = defaultClock;
      interface deleteme_unused_reset = defaultReset;
   endinterface
`endif
endmodule
endpackage


cleanup

cleanup

// Copyright (c) 2014 Cornell University.

// 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.

package EthPhy;

import Clocks                        ::*;
import Vector                        ::*;
import Connectable                   ::*;
import Pipe                          ::*;
import FIFO                          ::*;
import BRAMFIFO                      ::*;
import FIFOF                         ::*;
import SpecialFIFOs                  ::*;
import GetPut                        ::*;
import Ethernet                      ::*;
import EthSonicPma                   ::*;
import EthPcsTx                      ::*;
import EthPcsRx                      ::*;
import DtpTx                         ::*;
import DtpRx                         ::*;
import DtpSwitch                     ::*;
import DtpDCFifo            ::*;
import ALTERA_SI570_WRAPPER          ::*;
import ALTERA_EDGE_DETECTOR_WRAPPER  ::*;
import AlteraExtra                   ::*;

`ifdef NUMBER_OF_10G_PORTS
typedef `NUMBER_OF_10G_PORTS NumPorts;
`else
typedef 4 NumPorts;
`endif

interface EthPhyIfc#(numeric type numPorts);
   interface Vector#(numPorts, PipeIn#(Bit#(72)))  tx;
   interface Vector#(numPorts, PipeOut#(Bit#(72))) rx;
   (* always_ready, always_enabled *)
   interface Vector#(numPorts, SerialIfc) serial;
   interface Vector#(numPorts, Clock) tx_clkout;
   interface Vector#(numPorts, Clock) rx_clkout;
   (* always_ready, always_enabled *)
   interface LoopbackIfc loopback;

   interface Vector#(numPorts, Bool) led_rx_ready;
   interface Vector#(numPorts, DtpToPhyIfc) api;
   interface PipeIn#(Bit#(1)) switchMode;
   interface PipeOut#(Bit#(53)) globalOut;
endinterface

function Bit#(n) reverseBits(Bit#(n) x);
   Vector#(n, Bit#(1)) vx = unpack(x);
   Vector#(n, Bit#(1)) rvx = Vector::reverse(vx);
   Bit#(n) prvx = pack(rvx);
   return(prvx);
endfunction

(* synthesize *)
module mkEthPhy#(Clock mgmt_clk, Clock clk_156_25, Clock clk_644, Reset rst_n)(EthPhyIfc#(NumPorts));

   Reg#(Bit#(32)) cycle <- mkReg(0);
   Reset rst_50_n <- mkAsyncReset(2, rst_n, mgmt_clk);
   Reset rst_156_25_n <- mkAsyncReset(2, rst_n, clk_156_25);

   Reg#(Bool) loopback_en <- mkReg(False);
   Reg#(Bool) switch_en <- mkReg(False);

   Vector#(NumPorts, EthPcsRx) pcs_rx = newVector;
   Vector#(NumPorts, EthPcsTx) pcs_tx = newVector;
   Vector#(NumPorts, DtpRx)    dtp_rx = newVector;
   Vector#(NumPorts, DtpTx)    dtp_tx = newVector;

   EthSonicPma#(NumPorts)      pma4 <- mkEthSonicPma(mgmt_clk, clk_644, clk_156_25, rst_50_n, clocked_by mgmt_clk, reset_by rst_50_n);

   Vector#(NumPorts, ReadOnly#(Bool)) rx_ready_tx;
   Vector#(NumPorts, ReadOnly#(Bool)) tx_ready_tx;
   Vector#(NumPorts, ReadOnly#(Bool)) rx_ready_rx;
   Vector#(NumPorts, ReadOnly#(Bool)) tx_ready_rx;
   Vector#(NumPorts, CrossingReg#(Bool)) lock_tx;
   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      rx_ready_tx[i] <- mkNullCrossingWire(clk_156_25, pma4.rx_ready[i]);
      tx_ready_tx[i] <- mkNullCrossingWire(clk_156_25, pma4.tx_ready[i]);
      rx_ready_rx[i] <- mkNullCrossingWire(pma4.rx_clkout[i], pma4.rx_ready[i]);
      tx_ready_rx[i] <- mkNullCrossingWire(pma4.rx_clkout[i], pma4.tx_ready[i]);
      lock_tx[i] <- mkNullCrossingReg(clk_156_25, False, clocked_by pma4.rx_clkout[i], reset_by pma4.rx_reset[i]);
   end

   Vector#(NumPorts, FIFOF#(Bit#(72)))   txFifo     = newVector;
   Vector#(NumPorts, FIFOF#(Bit#(72)))   rxFifo     = newVector;
   Vector#(NumPorts, PipeIn#(Bit#(72)))  vRxPipeIn  = newVector;
   Vector#(NumPorts, PipeOut#(Bit#(72))) vRxPipeOut = newVector;
   Vector#(NumPorts, PipeIn#(Bit#(72)))  vTxPipeIn  = newVector;
   Vector#(NumPorts, PipeOut#(Bit#(72))) vTxPipeOut = newVector;

   // Loopback FIFO
   Vector#(NumPorts, SyncFIFOIfc#(Bit#(66))) lpbkSyncFifo = newVector;
   Vector#(NumPorts, PipeOut#(Bit#(66))) lpbkSyncPipeOut = newVector;
   Vector#(NumPorts, PipeIn#(Bit#(66))) lpbkSyncPipeIn = newVector;

   // DtpRx to DtpTx Fifo
   Vector#(NumPorts, SyncFIFOIfc#(DtpEvent)) dtpEventFifo = newVector;
   Vector#(NumPorts, PipeOut#(DtpEvent)) dtpEventOut = newVector;
   Vector#(NumPorts, PipeIn#(DtpEvent)) dtpEventIn = newVector;
   Vector#(NumPorts, SyncFIFOIfc#(Bit#(32))) dtpErrCntFifo = newVector;
   Vector#(NumPorts, PipeOut#(Bit#(32))) dtpErrCntOut = newVector;
   Vector#(NumPorts, PipeIn#(Bit#(32))) dtpErrCntIn = newVector;

   // 156.25MHz to pma4.tx
   Vector#(NumPorts, SyncFIFOIfc#(Bit#(66))) txSyncFifo = newVector;

   FIFOF#(Bit#(1)) switchModeFifo <- mkFIFOF();

   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      rxFifo[i] <- mkFIFOF(clocked_by pma4.rx_clkout[i], reset_by pma4.rx_reset[i]);
      txFifo[i] <- mkFIFOF(clocked_by clk_156_25, reset_by rst_156_25_n);
      vRxPipeIn[i] = toPipeIn(rxFifo[i]);
      vRxPipeOut[i] = toPipeOut(rxFifo[i]);
      vTxPipeIn[i] = toPipeIn(txFifo[i]);
      vTxPipeOut[i] = toPipeOut(txFifo[i]);

      // Gearbox Level Loopback FIFO
      lpbkSyncFifo[i] <- mkSyncFIFO(10, clk_156_25, rst_156_25_n, pma4.rx_clkout[i]);//, pma4.rx_reset[i]);
      lpbkSyncPipeOut[i] = toPipeOut(lpbkSyncFifo[i]);
      lpbkSyncPipeIn[i] = toPipeIn(lpbkSyncFifo[i]);

      pcs_rx[i]    <- mkEthPcsRxTop(clocked_by pma4.rx_clkout[i], reset_by pma4.rx_reset[i]);
      pcs_tx[i]    <- mkEthPcsTxTop(clocked_by clk_156_25, reset_by rst_156_25_n);
      dtp_rx[i]    <- mkDtpRxTop(clocked_by pma4.rx_clkout[i], reset_by pma4.rx_reset[i]);
      dtp_tx[i]    <- mkDtpTxTop(clocked_by clk_156_25, reset_by rst_156_25_n);

      dtpEventFifo[i] <- mkSyncFIFO(10, pma4.rx_clkout[i], pma4.rx_reset[i], clk_156_25);//, rst_156_25_n);
      //dtpEventFifo[i] <- mkDtpDCFifo(pma4.rx_clkout[i], pma4.rx_reset[i], clk_156_25);//, rst_156_25_n);
      dtpEventOut[i] = toPipeOut(dtpEventFifo[i]);
      dtpEventIn[i]  = toPipeIn(dtpEventFifo[i]);

      dtpErrCntFifo[i] <- mkSyncFIFO(10, pma4.rx_clkout[i], pma4.rx_reset[i], clk_156_25);//, rst_156_25_n);
      dtpErrCntOut[i] = toPipeOut(dtpErrCntFifo[i]);
      dtpErrCntIn[i]  = toPipeIn(dtpErrCntFifo[i]);

      // Rx Path: PcsRx -> DtpRx
      mkConnection(pcs_rx[i].dtpRxIn, dtp_rx[i].dtpRxIn);
      // Rx Path: DtpRx -> PcsRx
      mkConnection(dtp_rx[i].dtpRxOut, pcs_rx[i].dtpRxOut);
      // Rx Path: DtpRx -> SyncFIFO
      mkConnection(dtp_rx[i].dtpEventOut, dtpEventIn[i]);
      // Rx Path DtpRx -> SyncFifo
      mkConnection(dtp_rx[i].dtpErrCnt, dtpErrCntIn[i]);

      // Tx Path SyncFIfo -> DtpTx
      mkConnection(dtpErrCntOut[i], dtp_tx[i].dtpErrCnt);
      // Tx Path; SyncFifo -> DtpTx
      mkConnection(dtpEventOut[i], dtp_tx[i].dtpEventIn);
      // Tx Path: Mac -> Encoder
      mkConnection(vTxPipeOut[i], pcs_tx[i].encoderIn);
      // Tx Path: PcsTx -> DtpTx
      mkConnection(pcs_tx[i].dtpTxIn, dtp_tx[i].dtpTxIn);
      // Tx Path: DtpTx -> PcsTx
      mkConnection(dtp_tx[i].dtpTxOut, pcs_tx[i].dtpTxOut);

      // Loopback Enable Signal
      //ReadOnly#(Bool) rx_lpbk_en <- mkNullCrossingWire(pma4.rx_clkout[i], loopback_en);
      //ReadOnly#(Bool) tx_lpbk_en <- mkNullCrossingWire(clk_156_25, loopback_en);
      let rx_lpbk_en = False;
      let tx_lpbk_en = False;

      rule cross_lock_tx;
         lock_tx[i] <= pcs_rx[i].lock;
      endrule

      // Normal Operation: XCVR -> Pcs
      rule rx_no_loopback(!rx_lpbk_en);
         let v <- toGet(pma4.rx[i]).get;
         let reversed_v = reverseBits(v);
         pcs_rx[i].bsyncIn.enq(reversed_v);
      endrule
      rule tx_no_loopback(!tx_lpbk_en);
         let v <- toGet(pcs_tx[i].scramblerOut).get;
         let reversed_v = reverseBits(v);
         pma4.tx[i].enq(reversed_v);
      endrule
      // END Normal Operation

      // Loopback Operation: Pcs -> lpbk Fifo -> Pcs
      ReadOnly#(Bit#(32)) cycle_cross <- mkNullCrossingWire(clk_156_25, cycle);
      rule tx_loopback(tx_lpbk_en);
         let v <- toGet(pcs_tx[i].scramblerOut).get;
         lpbkSyncPipeIn[i].enq(v);
      endrule
      rule tx_pma_loopback(tx_lpbk_en);
         // Make sure PMA is up by sending fake data.
         Bit#(66) count = 66'hAAAAA55555AAAAAA;
         pma4.tx[i].enq(count);
      endrule
      rule rx_loopback(rx_lpbk_en);
         let v <- toGet(lpbkSyncPipeOut[i]).get;
         pcs_rx[i].bsyncIn.enq(v);
      endrule
      rule rx_pma_loopback(rx_lpbk_en);
         let v <- toGet(pma4.rx[i]).get;
      endrule
      // END Loopback Operation
   end

   rule cyc;
      cycle <= cycle + 1;
   endrule

   ReadOnly#(Bool) switch_en_tx;
   switch_en_tx <- mkNullCrossingWire(clk_156_25, switch_en);

   DtpSwitch#(4) dtpswitch <- mkDtpSwitch(clocked_by clk_156_25, reset_by rst_156_25_n);
   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      mkConnection(dtp_tx[i].dtpLocalOut, dtpswitch.dtpLocalIn[i]);
      mkConnection(dtpswitch.dtpGlobalOut[i], dtp_tx[i].dtpGlobalIn);
   end

   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      rule pcs_tx_every1;
         pcs_tx[i].tx_ready(tx_ready_tx[i]);
      endrule
      rule pcs_rx_every1;
         pcs_rx[i].rx_ready(rx_ready_rx[i]);
      endrule
      rule dtp_tx_every1;
         dtp_tx[i].tx_ready(tx_ready_tx[i]);
         dtp_tx[i].rx_ready(rx_ready_tx[i]);
         dtp_tx[i].switch_mode(switch_en_tx);
         dtp_tx[i].bsync_lock(lock_tx[i].crossed);
      endrule
      rule dtp_rx_every1;
         dtp_rx[i].rx_ready(rx_ready_rx[i]);
         dtp_rx[i].bsync_lock(pcs_rx[i].lock);
      endrule
   end

   rule switch_mode;
      let v <- toGet(switchModeFifo).get;
      switch_en <= unpack(v);
   endrule

   rule dtpswitch_mode;
      dtpswitch.switch_mode(switch_en_tx);
   endrule

   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      rule receive;
         let v <- toGet(pcs_rx[i].decoderOut).get;
         vRxPipeIn[i].enq(v);
      endrule
   end

   Vector#(NumPorts, DtpToPhyIfc) vapi;
   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      vapi[i] = dtp_tx[i].api;
   end

   interface loopback = (interface LoopbackIfc;
      method Action lpbk_en (Bool en);
         loopback_en <= en;
      endmethod
   endinterface);

   interface rx_clkout = pma4.rx_clkout;
   interface tx_clkout = pma4.tx_clkout;
   interface serial = pma4.pmd;
   interface rx = vRxPipeOut;
   interface tx = vTxPipeIn;
   interface led_rx_ready = pma4.rx_ready;

   interface api = vapi;
   interface switchMode = toPipeIn(switchModeFifo);
   interface globalOut = dtpswitch.globalOut;

endmodule: mkEthPhy
endpackage: EthPhy

// Copyright (c) 2014 Cornell University.

// 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.

package EthPhy;

import Clocks                        ::*;
import Vector                        ::*;
import Connectable                   ::*;
import Pipe                          ::*;
import FIFO                          ::*;
import BRAMFIFO                      ::*;
import FIFOF                         ::*;
import SpecialFIFOs                  ::*;
import GetPut                        ::*;
import Ethernet                      ::*;
import EthSonicPma                   ::*;
import EthPcsTx                      ::*;
import EthPcsRx                      ::*;
import DtpTx                         ::*;
import DtpRx                         ::*;
import DtpSwitch                     ::*;
//import DTP_DCFIFO_WRAPPER            ::*;
import DtpDCFifo            ::*;
import ALTERA_SI570_WRAPPER          ::*;
import ALTERA_EDGE_DETECTOR_WRAPPER  ::*;
import AlteraExtra                   ::*;

`ifdef NUMBER_OF_10G_PORTS
typedef `NUMBER_OF_10G_PORTS NumPorts;
`else
typedef 4 NumPorts;
`endif

interface EthPhyIfc#(numeric type numPorts);
   interface Vector#(numPorts, PipeIn#(Bit#(72)))  tx;
   interface Vector#(numPorts, PipeOut#(Bit#(72))) rx;
   (* always_ready, always_enabled *)
   interface Vector#(numPorts, SerialIfc) serial;
   interface Vector#(numPorts, Clock) tx_clkout;
   interface Vector#(numPorts, Clock) rx_clkout;
   (* always_ready, always_enabled *)
   interface LoopbackIfc loopback;

   interface Vector#(numPorts, Bool) led_rx_ready;
   interface Vector#(numPorts, DtpToPhyIfc) api;
   interface PipeIn#(Bit#(1)) switchMode;
   interface PipeOut#(Bit#(53)) globalOut;
endinterface

function Bit#(n) reverseBits(Bit#(n) x);
   Vector#(n, Bit#(1)) vx = unpack(x);
   Vector#(n, Bit#(1)) rvx = Vector::reverse(vx);
   Bit#(n) prvx = pack(rvx);
   return(prvx);
endfunction

(* synthesize *)
module mkEthPhy#(Clock mgmt_clk, Clock clk_156_25, Clock clk_644, Reset rst_n)(EthPhyIfc#(NumPorts));

   Reg#(Bit#(32)) cycle <- mkReg(0);
   Reset rst_50_n <- mkAsyncReset(2, rst_n, mgmt_clk);
   Reset rst_156_25_n <- mkAsyncReset(2, rst_n, clk_156_25);

   Reg#(Bool) loopback_en <- mkReg(False);
   Reg#(Bool) switch_en <- mkReg(False);

   Vector#(NumPorts, EthPcsRx) pcs_rx = newVector;
   Vector#(NumPorts, EthPcsTx) pcs_tx = newVector;
   Vector#(NumPorts, DtpRx)    dtp_rx = newVector;
   Vector#(NumPorts, DtpTx)    dtp_tx = newVector;

   EthSonicPma#(NumPorts)      pma4 <- mkEthSonicPma(mgmt_clk, clk_644, clk_156_25, rst_50_n, clocked_by mgmt_clk, reset_by rst_50_n);

   Vector#(NumPorts, ReadOnly#(Bool)) rx_ready_tx;
   Vector#(NumPorts, ReadOnly#(Bool)) tx_ready_tx;
   Vector#(NumPorts, ReadOnly#(Bool)) rx_ready_rx;
   Vector#(NumPorts, ReadOnly#(Bool)) tx_ready_rx;
   Vector#(NumPorts, CrossingReg#(Bool)) lock_tx;
   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      rx_ready_tx[i] <- mkNullCrossingWire(clk_156_25, pma4.rx_ready[i]);
      tx_ready_tx[i] <- mkNullCrossingWire(clk_156_25, pma4.tx_ready[i]);
      rx_ready_rx[i] <- mkNullCrossingWire(pma4.rx_clkout[i], pma4.rx_ready[i]);
      tx_ready_rx[i] <- mkNullCrossingWire(pma4.rx_clkout[i], pma4.tx_ready[i]);
      lock_tx[i] <- mkNullCrossingReg(clk_156_25, False, clocked_by pma4.rx_clkout[i], reset_by pma4.rx_reset[i]);
   end

   Vector#(NumPorts, FIFOF#(Bit#(72)))   txFifo     = newVector;
   Vector#(NumPorts, FIFOF#(Bit#(72)))   rxFifo     = newVector;
   Vector#(NumPorts, PipeIn#(Bit#(72)))  vRxPipeIn  = newVector;
   Vector#(NumPorts, PipeOut#(Bit#(72))) vRxPipeOut = newVector;
   Vector#(NumPorts, PipeIn#(Bit#(72)))  vTxPipeIn  = newVector;
   Vector#(NumPorts, PipeOut#(Bit#(72))) vTxPipeOut = newVector;

   // Loopback FIFO
   Vector#(NumPorts, SyncFIFOIfc#(Bit#(66))) lpbkSyncFifo = newVector;
   Vector#(NumPorts, PipeOut#(Bit#(66))) lpbkSyncPipeOut = newVector;
   Vector#(NumPorts, PipeIn#(Bit#(66))) lpbkSyncPipeIn = newVector;

   // DtpRx to DtpTx Fifo
   Vector#(NumPorts, SyncFIFOIfc#(DtpEvent)) dtpEventFifo = newVector;
   Vector#(NumPorts, PipeOut#(DtpEvent)) dtpEventOut = newVector;
   Vector#(NumPorts, PipeIn#(DtpEvent)) dtpEventIn = newVector;
   Vector#(NumPorts, SyncFIFOIfc#(Bit#(32))) dtpErrCntFifo = newVector;
   Vector#(NumPorts, PipeOut#(Bit#(32))) dtpErrCntOut = newVector;
   Vector#(NumPorts, PipeIn#(Bit#(32))) dtpErrCntIn = newVector;

   // 156.25MHz to pma4.tx
   Vector#(NumPorts, SyncFIFOIfc#(Bit#(66))) txSyncFifo = newVector;

   FIFOF#(Bit#(1)) switchModeFifo <- mkFIFOF();

   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      rxFifo[i] <- mkFIFOF(clocked_by pma4.rx_clkout[i], reset_by pma4.rx_reset[i]);
      txFifo[i] <- mkFIFOF(clocked_by clk_156_25, reset_by rst_156_25_n);
      vRxPipeIn[i] = toPipeIn(rxFifo[i]);
      vRxPipeOut[i] = toPipeOut(rxFifo[i]);
      vTxPipeIn[i] = toPipeIn(txFifo[i]);
      vTxPipeOut[i] = toPipeOut(txFifo[i]);

      // Gearbox Level Loopback FIFO
      lpbkSyncFifo[i] <- mkSyncFIFO(10, clk_156_25, rst_156_25_n, pma4.rx_clkout[i]);//, pma4.rx_reset[i]);
      lpbkSyncPipeOut[i] = toPipeOut(lpbkSyncFifo[i]);
      lpbkSyncPipeIn[i] = toPipeIn(lpbkSyncFifo[i]);

      pcs_rx[i]    <- mkEthPcsRxTop(clocked_by pma4.rx_clkout[i], reset_by pma4.rx_reset[i]);
      pcs_tx[i]    <- mkEthPcsTxTop(clocked_by clk_156_25, reset_by rst_156_25_n);
      dtp_rx[i]    <- mkDtpRxTop(clocked_by pma4.rx_clkout[i], reset_by pma4.rx_reset[i]);
      dtp_tx[i]    <- mkDtpTxTop(clocked_by clk_156_25, reset_by rst_156_25_n);

      dtpEventFifo[i] <- mkSyncFIFO(10, pma4.rx_clkout[i], pma4.rx_reset[i], clk_156_25);//, rst_156_25_n);
      //dtpEventFifo[i] <- mkDtpDCFifo(pma4.rx_clkout[i], pma4.rx_reset[i], clk_156_25);//, rst_156_25_n);
      dtpEventOut[i] = toPipeOut(dtpEventFifo[i]);
      dtpEventIn[i]  = toPipeIn(dtpEventFifo[i]);

      dtpErrCntFifo[i] <- mkSyncFIFO(10, pma4.rx_clkout[i], pma4.rx_reset[i], clk_156_25);//, rst_156_25_n);
      dtpErrCntOut[i] = toPipeOut(dtpErrCntFifo[i]);
      dtpErrCntIn[i]  = toPipeIn(dtpErrCntFifo[i]);

      // Rx Path: PcsRx -> DtpRx
      mkConnection(pcs_rx[i].dtpRxIn, dtp_rx[i].dtpRxIn);
      // Rx Path: DtpRx -> PcsRx
      mkConnection(dtp_rx[i].dtpRxOut, pcs_rx[i].dtpRxOut);
      // Rx Path: DtpRx -> SyncFIFO
      mkConnection(dtp_rx[i].dtpEventOut, dtpEventIn[i]);
      // Rx Path DtpRx -> SyncFifo
      mkConnection(dtp_rx[i].dtpErrCnt, dtpErrCntIn[i]);

      // Tx Path SyncFIfo -> DtpTx
      mkConnection(dtpErrCntOut[i], dtp_tx[i].dtpErrCnt);
      // Tx Path; SyncFifo -> DtpTx
      mkConnection(dtpEventOut[i], dtp_tx[i].dtpEventIn);
      // Tx Path: Mac -> Encoder
      mkConnection(vTxPipeOut[i], pcs_tx[i].encoderIn);
      // Tx Path: PcsTx -> DtpTx
      mkConnection(pcs_tx[i].dtpTxIn, dtp_tx[i].dtpTxIn);
      // Tx Path: DtpTx -> PcsTx
      mkConnection(dtp_tx[i].dtpTxOut, pcs_tx[i].dtpTxOut);

      // Loopback Enable Signal
      //ReadOnly#(Bool) rx_lpbk_en <- mkNullCrossingWire(pma4.rx_clkout[i], loopback_en);
      //ReadOnly#(Bool) tx_lpbk_en <- mkNullCrossingWire(clk_156_25, loopback_en);
      let rx_lpbk_en = False;
      let tx_lpbk_en = False;

      rule cross_lock_tx;
         lock_tx[i] <= pcs_rx[i].lock;
      endrule

      // Normal Operation: XCVR -> Pcs
      rule rx_no_loopback(!rx_lpbk_en);
         let v <- toGet(pma4.rx[i]).get;
         let reversed_v = reverseBits(v);
         pcs_rx[i].bsyncIn.enq(reversed_v);
      endrule
      rule tx_no_loopback(!tx_lpbk_en);
         let v <- toGet(pcs_tx[i].scramblerOut).get;
         let reversed_v = reverseBits(v);
         pma4.tx[i].enq(reversed_v);
      endrule
      // END Normal Operation

      // Loopback Operation: Pcs -> lpbk Fifo -> Pcs
      ReadOnly#(Bit#(32)) cycle_cross <- mkNullCrossingWire(clk_156_25, cycle);
      rule tx_loopback(tx_lpbk_en);
         let v <- toGet(pcs_tx[i].scramblerOut).get;
         lpbkSyncPipeIn[i].enq(v);
      endrule
      rule tx_pma_loopback(tx_lpbk_en);
         // Make sure PMA is up by sending fake data.
         Bit#(66) count = 66'hAAAAA55555AAAAAA;
         pma4.tx[i].enq(count);
      endrule
      rule rx_loopback(rx_lpbk_en);
         let v <- toGet(lpbkSyncPipeOut[i]).get;
         pcs_rx[i].bsyncIn.enq(v);
      endrule
      rule rx_pma_loopback(rx_lpbk_en);
         let v <- toGet(pma4.rx[i]).get;
      endrule
      // END Loopback Operation
   end

   rule cyc;
      cycle <= cycle + 1;
   endrule

   ReadOnly#(Bool) switch_en_tx;
   switch_en_tx <- mkNullCrossingWire(clk_156_25, switch_en);

   DtpSwitch#(4) dtpswitch <- mkDtpSwitch(clocked_by clk_156_25, reset_by rst_156_25_n);
   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      mkConnection(dtp_tx[i].dtpLocalOut, dtpswitch.dtpLocalIn[i]);
      mkConnection(dtpswitch.dtpGlobalOut[i], dtp_tx[i].dtpGlobalIn);
   end

   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      rule pcs_tx_every1;
         pcs_tx[i].tx_ready(tx_ready_tx[i]);
      endrule
      rule pcs_rx_every1;
         pcs_rx[i].rx_ready(rx_ready_rx[i]);
      endrule
      rule dtp_tx_every1;
         dtp_tx[i].tx_ready(tx_ready_tx[i]);
         dtp_tx[i].rx_ready(rx_ready_tx[i]);
         dtp_tx[i].switch_mode(switch_en_tx);
         dtp_tx[i].bsync_lock(lock_tx[i].crossed);
      endrule
      rule dtp_rx_every1;
         dtp_rx[i].rx_ready(rx_ready_rx[i]);
         dtp_rx[i].bsync_lock(pcs_rx[i].lock);
      endrule
   end

   rule switch_mode;
      let v <- toGet(switchModeFifo).get;
      switch_en <= unpack(v);
   endrule

   rule dtpswitch_mode;
      dtpswitch.switch_mode(switch_en_tx);
   endrule

   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      rule receive;
         let v <- toGet(pcs_rx[i].decoderOut).get;
         vRxPipeIn[i].enq(v);
      endrule
   end

   Vector#(NumPorts, DtpToPhyIfc) vapi;
   for (Integer i=0; i<valueOf(NumPorts); i=i+1) begin
      vapi[i] = dtp_tx[i].api;
   end

   interface loopback = (interface LoopbackIfc;
      method Action lpbk_en (Bool en);
         loopback_en <= en;
      endmethod
   endinterface);

   interface rx_clkout = pma4.rx_clkout;
   interface tx_clkout = pma4.tx_clkout;
   interface serial = pma4.pmd;
   interface rx = vRxPipeOut;
   interface tx = vTxPipeIn;
   interface led_rx_ready = pma4.rx_ready;

   interface api = vapi;
   interface switchMode = toPipeIn(switchModeFifo);
   interface globalOut = dtpswitch.globalOut;

endmodule: mkEthPhy
endpackage: EthPhy