axi stream clocks

axi stream clocks

/*
   ../scripts/importbvi.py
   -o
   AxiEthBvi.bsv
   -P
   AxiEthBvi
   -I
   AxiEthBvi
   ../../out/vc709/axi_ethernet_0/axi_ethernet_0_stub.v
*/

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

(* always_ready, always_enabled *)
interface AxiethbviAxi;
    method Action      rxd_arstn(Bit#(1) v);
    method Action      rxs_arstn(Bit#(1) v);
    method Action      txc_arstn(Bit#(1) v);
    method Action      txd_arstn(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviGt;
    method Bit#(1)     qplloutclk_out();
    method Bit#(1)     qplloutrefclk_out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviGtref;
    method Bit#(1)     clk_buf_out();
    method Bit#(1)     clk_out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviMac;
    method Bit#(1)     irq();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviMdio;
    method Bit#(1)     mdc();
    method Action      mdio_i(Bit#(1) v);
    method Bit#(1)     mdio_o();
    method Bit#(1)     mdio_t();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviMgt;
    method Action      clk_clk_n(Bit#(1) v);
    method Action      clk_clk_p(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviMmcm;
    method Bit#(1)     locked_out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviPhy;
    method Bit#(1)     rst_n();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviPma;
    method Bit#(1)     reset_out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviRef;
    method Action      clk(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviRxuserclk;
    method Bit#(1)     out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviS_axi;
    method Action      araddr(Bit#(18) v);
    method Bit#(1)     arready();
    method Action      arvalid(Bit#(1) v);
    method Action      awaddr(Bit#(18) v);
    method Bit#(1)     awready();
    method Action      awvalid(Bit#(1) v);
    method Action      bready(Bit#(1) v);
    method Bit#(2)     bresp();
    method Bit#(1)     bvalid();
    method Bit#(32)     rdata();
    method Action      rready(Bit#(1) v);
    method Bit#(2)     rresp();
    method Bit#(1)     rvalid();
    method Action      wdata(Bit#(32) v);
    method Bit#(1)     wready();
    method Action      wstrb(Bit#(4) v);
    method Action      wvalid(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviSgmii;
    method Action      rxn(Bit#(1) v);
    method Action      rxp(Bit#(1) v);
    method Bit#(1)     txn();
    method Bit#(1)     txp();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviSignal;
    method Action      detect(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviUserclk;
    method Bit#(1)     out();
endinterface
(* always_ready, always_enabled *)
interface AxiEthBvi;
    interface AxiethbviAxi     axi;
    interface AxiethbviGt     gt0;
    interface AxiethbviGtref     gtref;
    method Bit#(1)     interrupt();
    interface AxiStreamMaster#(32)     m_axis_rxd;
    interface AxiStreamMaster#(32)     m_axis_rxs;
    interface AxiethbviMac     mac;
    interface AxiethbviMdio     mdio;
    interface AxiethbviMgt     mgt;
    interface AxiethbviMmcm     mmcm;
    interface AxiethbviPhy     phy;
    interface AxiethbviPma     pma;
    interface AxiethbviRef     reff;
    interface AxiethbviRxuserclk     rxuserclk2;
    interface AxiethbviRxuserclk     rxuserclk;
    interface AxiethbviS_axi     s_axi;
    interface AxiStreamSlave#(32)     s_axis_txc;
    interface AxiStreamSlave#(32)     s_axis_txd;
    interface AxiethbviSgmii     sgmii;
    interface AxiethbviSignal     signal;
    interface AxiethbviUserclk     userclk2;
    interface AxiethbviUserclk     userclk;
endinterface
import "BVI" axi_ethernet_0 =
module mkAxiEthBvi#(Clock s_axi_clk, Reset s_axi_reset, Clock axis_clk)(AxiEthBvi);
    default_clock clk();
    default_reset rst();
    input_clock (s_axi_lite_clk) = s_axi_clk;
    input_reset (s_axi_lite_resetn) = s_axi_reset;
    input_clock (axis_clk) = axis_clk;
    interface AxiethbviAxi     axi;
        method rxd_arstn(axi_rxd_arstn) enable((*inhigh*) EN_axi_rxd_arstn) clocked_by (axis_clk);
        method rxs_arstn(axi_rxs_arstn) enable((*inhigh*) EN_axi_rxs_arstn) clocked_by (axis_clk);
        method txc_arstn(axi_txc_arstn) enable((*inhigh*) EN_axi_txc_arstn) clocked_by (axis_clk);
        method txd_arstn(axi_txd_arstn) enable((*inhigh*) EN_axi_txd_arstn) clocked_by (axis_clk);
    endinterface
    interface AxiethbviGt     gt0;
        method gt0_qplloutclk_out qplloutclk_out();
        method gt0_qplloutrefclk_out qplloutrefclk_out();
    endinterface
    interface AxiethbviGtref     gtref;
        method gtref_clk_buf_out clk_buf_out();
        method gtref_clk_out clk_out();
    endinterface
    method interrupt interrupt();
    interface AxiStreamMaster     m_axis_rxd;
        method m_axis_rxd_tdata tdata() clocked_by (axis_clk);
        method m_axis_rxd_tkeep tkeep() clocked_by (axis_clk);
        method m_axis_rxd_tlast tlast() clocked_by (axis_clk);
        method tready(m_axis_rxd_tready) enable((*inhigh*) EN_m_axis_rxd_tready) clocked_by (axis_clk);
        method m_axis_rxd_tvalid tvalid() clocked_by (axis_clk);
    endinterface
    interface AxiStreamMaster     m_axis_rxs;
        method m_axis_rxs_tdata tdata() clocked_by (axis_clk);
        method m_axis_rxs_tkeep tkeep() clocked_by (axis_clk);
        method m_axis_rxs_tlast tlast() clocked_by (axis_clk);
        method tready(m_axis_rxs_tready) enable((*inhigh*) EN_m_axis_rxs_tready) clocked_by (axis_clk);
        method m_axis_rxs_tvalid tvalid() clocked_by (axis_clk);
    endinterface
    interface AxiethbviMac     mac;
        method mac_irq irq();
    endinterface
    interface AxiethbviMdio     mdio;
        method mdio_mdc mdc();
        method mdio_i(mdio_mdio_i) enable((*inhigh*) EN_mdio_mdio_i);
        method mdio_mdio_o mdio_o();
        method mdio_mdio_t mdio_t();
    endinterface
    interface AxiethbviMgt     mgt;
        method clk_clk_n(mgt_clk_clk_n) enable((*inhigh*) EN_mgt_clk_clk_n);
        method clk_clk_p(mgt_clk_clk_p) enable((*inhigh*) EN_mgt_clk_clk_p);
    endinterface
    interface AxiethbviMmcm     mmcm;
        method mmcm_locked_out locked_out();
    endinterface
    interface AxiethbviPhy     phy;
        method phy_rst_n rst_n();
    endinterface
    interface AxiethbviPma     pma;
        method pma_reset_out reset_out();
    endinterface
    interface AxiethbviRef     reff;
        method clk(ref_clk) enable((*inhigh*) EN_ref_clk);
    endinterface
    interface AxiethbviRxuserclk     rxuserclk2;
        method rxuserclk2_out out();
    endinterface
    interface AxiethbviRxuserclk     rxuserclk;
        method rxuserclk_out out();
    endinterface
    interface AxiethbviS_axi     s_axi;
        method araddr(s_axi_araddr) enable((*inhigh*) EN_s_axi_araddr) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_arready arready() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method arvalid(s_axi_arvalid) enable((*inhigh*) EN_s_axi_arvalid) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method awaddr(s_axi_awaddr) enable((*inhigh*) EN_s_axi_awaddr) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_awready awready() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method awvalid(s_axi_awvalid) enable((*inhigh*) EN_s_axi_awvalid) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method bready(s_axi_bready) enable((*inhigh*) EN_s_axi_bready) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_bresp bresp() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_bvalid bvalid() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_rdata rdata() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method rready(s_axi_rready) enable((*inhigh*) EN_s_axi_rready) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_rresp rresp() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_rvalid rvalid() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method wdata(s_axi_wdata) enable((*inhigh*) EN_s_axi_wdata) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_wready wready() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method wstrb(s_axi_wstrb) enable((*inhigh*) EN_s_axi_wstrb) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method wvalid(s_axi_wvalid) enable((*inhigh*) EN_s_axi_wvalid) clocked_by (s_axi_clk) reset_by (s_axi_reset);
    endinterface
    interface AxiStreamSlave     s_axis_txc;
        method tdata(s_axis_txc_tdata) enable((*inhigh*) EN_s_axis_txc_tdata);
        method tkeep(s_axis_txc_tkeep) enable((*inhigh*) EN_s_axis_txc_tkeep);
        method tlast(s_axis_txc_tlast) enable((*inhigh*) EN_s_axis_txc_tlast);
        method s_axis_txc_tready tready();
        method tvalid(s_axis_txc_tvalid) enable((*inhigh*) EN_s_axis_txc_tvalid);
    endinterface
    interface AxiStreamSlave     s_axis_txd;
        method tdata(s_axis_txd_tdata) enable((*inhigh*) EN_s_axis_txd_tdata);
        method tkeep(s_axis_txd_tkeep) enable((*inhigh*) EN_s_axis_txd_tkeep);
        method tlast(s_axis_txd_tlast) enable((*inhigh*) EN_s_axis_txd_tlast);
        method s_axis_txd_tready tready();
        method tvalid(s_axis_txd_tvalid) enable((*inhigh*) EN_s_axis_txd_tvalid);
    endinterface
    interface AxiethbviSgmii     sgmii;
        method rxn(sgmii_rxn) enable((*inhigh*) EN_sgmii_rxn);
        method rxp(sgmii_rxp) enable((*inhigh*) EN_sgmii_rxp);
        method sgmii_txn txn();
        method sgmii_txp txp();
    endinterface
    interface AxiethbviSignal     signal;
        method detect(signal_detect) enable((*inhigh*) EN_signal_detect);
    endinterface
    interface AxiethbviUserclk     userclk2;
        method userclk2_out out();
    endinterface
    interface AxiethbviUserclk     userclk;
        method userclk_out out();
    endinterface
    schedule (axi.rxd_arstn, axi.rxs_arstn, axi.txc_arstn, axi.txd_arstn, gt0.qplloutclk_out, gt0.qplloutrefclk_out, gtref.clk_buf_out, gtref.clk_out, interrupt, m_axis_rxd.tdata, m_axis_rxd.tkeep, m_axis_rxd.tlast, m_axis_rxd.tready, m_axis_rxd.tvalid, m_axis_rxs.tdata, m_axis_rxs.tkeep, m_axis_rxs.tlast, m_axis_rxs.tready, m_axis_rxs.tvalid, mac.irq, mdio.mdc, mdio.mdio_i, mdio.mdio_o, mdio.mdio_t, mgt.clk_clk_n, mgt.clk_clk_p, mmcm.locked_out, phy.rst_n, pma.reset_out, reff.clk, rxuserclk2.out, rxuserclk.out, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, s_axis_txc.tdata, s_axis_txc.tkeep, s_axis_txc.tlast, s_axis_txc.tready, s_axis_txc.tvalid, s_axis_txd.tdata, s_axis_txd.tkeep, s_axis_txd.tlast, s_axis_txd.tready, s_axis_txd.tvalid, sgmii.rxn, sgmii.rxp, sgmii.txn, sgmii.txp, signal.detect, userclk2.out, userclk.out) CF (axi.rxd_arstn, axi.rxs_arstn, axi.txc_arstn, axi.txd_arstn, gt0.qplloutclk_out, gt0.qplloutrefclk_out, gtref.clk_buf_out, gtref.clk_out, interrupt, m_axis_rxd.tdata, m_axis_rxd.tkeep, m_axis_rxd.tlast, m_axis_rxd.tready, m_axis_rxd.tvalid, m_axis_rxs.tdata, m_axis_rxs.tkeep, m_axis_rxs.tlast, m_axis_rxs.tready, m_axis_rxs.tvalid, mac.irq, mdio.mdc, mdio.mdio_i, mdio.mdio_o, mdio.mdio_t, mgt.clk_clk_n, mgt.clk_clk_p, mmcm.locked_out, phy.rst_n, pma.reset_out, reff.clk, rxuserclk2.out, rxuserclk.out, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, s_axis_txc.tdata, s_axis_txc.tkeep, s_axis_txc.tlast, s_axis_txc.tready, s_axis_txc.tvalid, s_axis_txd.tdata, s_axis_txd.tkeep, s_axis_txd.tlast, s_axis_txd.tready, s_axis_txd.tvalid, sgmii.rxn, sgmii.rxp, sgmii.txn, sgmii.txp, signal.detect, userclk2.out, userclk.out);
endmodule

/*
   ../scripts/importbvi.py
   -o
   AxiEthBvi.bsv
   -P
   AxiEthBvi
   -I
   AxiEthBvi
   ../../out/vc709/axi_ethernet_0/axi_ethernet_0_stub.v
*/

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

(* always_ready, always_enabled *)
interface AxiethbviAxi;
    method Action      rxd_arstn(Bit#(1) v);
    method Action      rxs_arstn(Bit#(1) v);
    method Action      txc_arstn(Bit#(1) v);
    method Action      txd_arstn(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviAxis;
    method Action      clk(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviGt;
    method Bit#(1)     qplloutclk_out();
    method Bit#(1)     qplloutrefclk_out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviGtref;
    method Bit#(1)     clk_buf_out();
    method Bit#(1)     clk_out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviMac;
    method Bit#(1)     irq();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviMdio;
    method Bit#(1)     mdc();
    method Action      mdio_i(Bit#(1) v);
    method Bit#(1)     mdio_o();
    method Bit#(1)     mdio_t();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviMgt;
    method Action      clk_clk_n(Bit#(1) v);
    method Action      clk_clk_p(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviMmcm;
    method Bit#(1)     locked_out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviPhy;
    method Bit#(1)     rst_n();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviPma;
    method Bit#(1)     reset_out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviRef;
    method Action      clk(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviRxuserclk;
    method Bit#(1)     out();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviS_axi;
    method Action      araddr(Bit#(18) v);
    method Bit#(1)     arready();
    method Action      arvalid(Bit#(1) v);
    method Action      awaddr(Bit#(18) v);
    method Bit#(1)     awready();
    method Action      awvalid(Bit#(1) v);
    method Action      bready(Bit#(1) v);
    method Bit#(2)     bresp();
    method Bit#(1)     bvalid();
    method Bit#(32)     rdata();
    method Action      rready(Bit#(1) v);
    method Bit#(2)     rresp();
    method Bit#(1)     rvalid();
    method Action      wdata(Bit#(32) v);
    method Bit#(1)     wready();
    method Action      wstrb(Bit#(4) v);
    method Action      wvalid(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviSgmii;
    method Action      rxn(Bit#(1) v);
    method Action      rxp(Bit#(1) v);
    method Bit#(1)     txn();
    method Bit#(1)     txp();
endinterface
(* always_ready, always_enabled *)
interface AxiethbviSignal;
    method Action      detect(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface AxiethbviUserclk;
    method Bit#(1)     out();
endinterface
(* always_ready, always_enabled *)
interface AxiEthBvi;
    interface AxiethbviAxi     axi;
    interface AxiethbviAxis     axis;
    interface AxiethbviGt     gt0;
    interface AxiethbviGtref     gtref;
    method Bit#(1)     interrupt();
    interface AxiStreamMaster#(32)     m_axis_rxd;
    interface AxiStreamMaster#(32)     m_axis_rxs;
    interface AxiethbviMac     mac;
    interface AxiethbviMdio     mdio;
    interface AxiethbviMgt     mgt;
    interface AxiethbviMmcm     mmcm;
    interface AxiethbviPhy     phy;
    interface AxiethbviPma     pma;
    interface AxiethbviRef     reff;
    interface AxiethbviRxuserclk     rxuserclk2;
    interface AxiethbviRxuserclk     rxuserclk;
    interface AxiethbviS_axi     s_axi;
    interface AxiStreamSlave#(32)     s_axis_txc;
    interface AxiStreamSlave#(32)     s_axis_txd;
    interface AxiethbviSgmii     sgmii;
    interface AxiethbviSignal     signal;
    interface AxiethbviUserclk     userclk2;
    interface AxiethbviUserclk     userclk;
endinterface
import "BVI" axi_ethernet_0 =
module mkAxiEthBvi#(Clock s_axi_clk, Reset s_axi_reset)(AxiEthBvi);
    default_clock clk();
    default_reset rst();
    input_clock (s_axi_lite_clk) = s_axi_clk;
    input_reset (s_axi_lite_resetn) = s_axi_reset;
    interface AxiethbviAxi     axi;
        method rxd_arstn(axi_rxd_arstn) enable((*inhigh*) EN_axi_rxd_arstn);
        method rxs_arstn(axi_rxs_arstn) enable((*inhigh*) EN_axi_rxs_arstn);
        method txc_arstn(axi_txc_arstn) enable((*inhigh*) EN_axi_txc_arstn);
        method txd_arstn(axi_txd_arstn) enable((*inhigh*) EN_axi_txd_arstn);
    endinterface
    interface AxiethbviAxis     axis;
        method clk(axis_clk) enable((*inhigh*) EN_axis_clk);
    endinterface
    interface AxiethbviGt     gt0;
        method gt0_qplloutclk_out qplloutclk_out();
        method gt0_qplloutrefclk_out qplloutrefclk_out();
    endinterface
    interface AxiethbviGtref     gtref;
        method gtref_clk_buf_out clk_buf_out();
        method gtref_clk_out clk_out();
    endinterface
    method interrupt interrupt();
    interface AxiStreamMaster     m_axis_rxd;
        method m_axis_rxd_tdata tdata();
        method m_axis_rxd_tkeep tkeep();
        method m_axis_rxd_tlast tlast();
        method tready(m_axis_rxd_tready) enable((*inhigh*) EN_m_axis_rxd_tready);
        method m_axis_rxd_tvalid tvalid();
    endinterface
    interface AxiStreamMaster     m_axis_rxs;
        method m_axis_rxs_tdata tdata();
        method m_axis_rxs_tkeep tkeep();
        method m_axis_rxs_tlast tlast();
        method tready(m_axis_rxs_tready) enable((*inhigh*) EN_m_axis_rxs_tready);
        method m_axis_rxs_tvalid tvalid();
    endinterface
    interface AxiethbviMac     mac;
        method mac_irq irq();
    endinterface
    interface AxiethbviMdio     mdio;
        method mdio_mdc mdc();
        method mdio_i(mdio_mdio_i) enable((*inhigh*) EN_mdio_mdio_i);
        method mdio_mdio_o mdio_o();
        method mdio_mdio_t mdio_t();
    endinterface
    interface AxiethbviMgt     mgt;
        method clk_clk_n(mgt_clk_clk_n) enable((*inhigh*) EN_mgt_clk_clk_n);
        method clk_clk_p(mgt_clk_clk_p) enable((*inhigh*) EN_mgt_clk_clk_p);
    endinterface
    interface AxiethbviMmcm     mmcm;
        method mmcm_locked_out locked_out();
    endinterface
    interface AxiethbviPhy     phy;
        method phy_rst_n rst_n();
    endinterface
    interface AxiethbviPma     pma;
        method pma_reset_out reset_out();
    endinterface
    interface AxiethbviRef     reff;
        method clk(ref_clk) enable((*inhigh*) EN_ref_clk);
    endinterface
    interface AxiethbviRxuserclk     rxuserclk2;
        method rxuserclk2_out out();
    endinterface
    interface AxiethbviRxuserclk     rxuserclk;
        method rxuserclk_out out();
    endinterface
    interface AxiethbviS_axi     s_axi;
        method araddr(s_axi_araddr) enable((*inhigh*) EN_s_axi_araddr) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_arready arready() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method arvalid(s_axi_arvalid) enable((*inhigh*) EN_s_axi_arvalid) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method awaddr(s_axi_awaddr) enable((*inhigh*) EN_s_axi_awaddr) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_awready awready() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method awvalid(s_axi_awvalid) enable((*inhigh*) EN_s_axi_awvalid) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method bready(s_axi_bready) enable((*inhigh*) EN_s_axi_bready) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_bresp bresp() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_bvalid bvalid() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_rdata rdata() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method rready(s_axi_rready) enable((*inhigh*) EN_s_axi_rready) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_rresp rresp() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_rvalid rvalid() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method wdata(s_axi_wdata) enable((*inhigh*) EN_s_axi_wdata) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method s_axi_wready wready() clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method wstrb(s_axi_wstrb) enable((*inhigh*) EN_s_axi_wstrb) clocked_by (s_axi_clk) reset_by (s_axi_reset);
        method wvalid(s_axi_wvalid) enable((*inhigh*) EN_s_axi_wvalid) clocked_by (s_axi_clk) reset_by (s_axi_reset);
    endinterface
    interface AxiStreamSlave     s_axis_txc;
        method tdata(s_axis_txc_tdata) enable((*inhigh*) EN_s_axis_txc_tdata);
        method tkeep(s_axis_txc_tkeep) enable((*inhigh*) EN_s_axis_txc_tkeep);
        method tlast(s_axis_txc_tlast) enable((*inhigh*) EN_s_axis_txc_tlast);
        method s_axis_txc_tready tready();
        method tvalid(s_axis_txc_tvalid) enable((*inhigh*) EN_s_axis_txc_tvalid);
    endinterface
    interface AxiStreamSlave     s_axis_txd;
        method tdata(s_axis_txd_tdata) enable((*inhigh*) EN_s_axis_txd_tdata);
        method tkeep(s_axis_txd_tkeep) enable((*inhigh*) EN_s_axis_txd_tkeep);
        method tlast(s_axis_txd_tlast) enable((*inhigh*) EN_s_axis_txd_tlast);
        method s_axis_txd_tready tready();
        method tvalid(s_axis_txd_tvalid) enable((*inhigh*) EN_s_axis_txd_tvalid);
    endinterface
    interface AxiethbviSgmii     sgmii;
        method rxn(sgmii_rxn) enable((*inhigh*) EN_sgmii_rxn);
        method rxp(sgmii_rxp) enable((*inhigh*) EN_sgmii_rxp);
        method sgmii_txn txn();
        method sgmii_txp txp();
    endinterface
    interface AxiethbviSignal     signal;
        method detect(signal_detect) enable((*inhigh*) EN_signal_detect);
    endinterface
    interface AxiethbviUserclk     userclk2;
        method userclk2_out out();
    endinterface
    interface AxiethbviUserclk     userclk;
        method userclk_out out();
    endinterface
    schedule (axi.rxd_arstn, axi.rxs_arstn, axi.txc_arstn, axi.txd_arstn, axis.clk, gt0.qplloutclk_out, gt0.qplloutrefclk_out, gtref.clk_buf_out, gtref.clk_out, interrupt, m_axis_rxd.tdata, m_axis_rxd.tkeep, m_axis_rxd.tlast, m_axis_rxd.tready, m_axis_rxd.tvalid, m_axis_rxs.tdata, m_axis_rxs.tkeep, m_axis_rxs.tlast, m_axis_rxs.tready, m_axis_rxs.tvalid, mac.irq, mdio.mdc, mdio.mdio_i, mdio.mdio_o, mdio.mdio_t, mgt.clk_clk_n, mgt.clk_clk_p, mmcm.locked_out, phy.rst_n, pma.reset_out, reff.clk, rxuserclk2.out, rxuserclk.out, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, s_axis_txc.tdata, s_axis_txc.tkeep, s_axis_txc.tlast, s_axis_txc.tready, s_axis_txc.tvalid, s_axis_txd.tdata, s_axis_txd.tkeep, s_axis_txd.tlast, s_axis_txd.tready, s_axis_txd.tvalid, sgmii.rxn, sgmii.rxp, sgmii.txn, sgmii.txp, signal.detect, userclk2.out, userclk.out) CF (axi.rxd_arstn, axi.rxs_arstn, axi.txc_arstn, axi.txd_arstn, axis.clk, gt0.qplloutclk_out, gt0.qplloutrefclk_out, gtref.clk_buf_out, gtref.clk_out, interrupt, m_axis_rxd.tdata, m_axis_rxd.tkeep, m_axis_rxd.tlast, m_axis_rxd.tready, m_axis_rxd.tvalid, m_axis_rxs.tdata, m_axis_rxs.tkeep, m_axis_rxs.tlast, m_axis_rxs.tready, m_axis_rxs.tvalid, mac.irq, mdio.mdc, mdio.mdio_i, mdio.mdio_o, mdio.mdio_t, mgt.clk_clk_n, mgt.clk_clk_p, mmcm.locked_out, phy.rst_n, pma.reset_out, reff.clk, rxuserclk2.out, rxuserclk.out, s_axi.araddr, s_axi.arready, s_axi.arvalid, s_axi.awaddr, s_axi.awready, s_axi.awvalid, s_axi.bready, s_axi.bresp, s_axi.bvalid, s_axi.rdata, s_axi.rready, s_axi.rresp, s_axi.rvalid, s_axi.wdata, s_axi.wready, s_axi.wstrb, s_axi.wvalid, s_axis_txc.tdata, s_axis_txc.tkeep, s_axis_txc.tlast, s_axis_txc.tready, s_axis_txc.tvalid, s_axis_txd.tdata, s_axis_txd.tkeep, s_axis_txd.tlast, s_axis_txd.tready, s_axis_txd.tvalid, sgmii.rxn, sgmii.rxp, sgmii.txn, sgmii.txp, signal.detect, userclk2.out, userclk.out);
endmodule


comment out mkAxi3MasterGather proviso without complaints.  Why was it there?

// 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 GetPut::*;
import Vector::*;
import PPS7LIB::*;
import AxiMasterSlave::*;
import AxiBits::*;

interface AxiMasterCommon#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth);
    method Bit#(1)            aresetn();
    interface Axi3Master#(addrWidth,dataWidth,tagWidth) client;
endinterface

interface AxiSlaveCommon#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth, type extraType);
    method Bit#(1)            aresetn();
    interface Axi3Slave#(addrWidth,dataWidth,tagWidth) server;
    interface extraType   extra;
endinterface

interface AxiMasterWires#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth);
   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;

   interface Wire#(Bit#(tagWidth)) rid;
   interface Wire#(Bit#(2))  rresp;
   interface Wire#(Bit#(dataWidth)) rdata;
   interface Wire#(Bit#(1))  rlast;
   interface Wire#(Bit#(tagWidth)) bid;
   interface Wire#(Bit#(2)) bresp;
endinterface

interface AxiSlaveWires#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth);
   interface Wire#(Bit#(addrWidth)) araddr;
   interface Wire#(Bit#(2)) arburst;
   interface Wire#(Bit#(4)) arcache;
   interface Wire#(Bit#(tagWidth)) arid;
   interface Wire#(Bit#(4)) arlen;
   interface Wire#(Bit#(2)) arlock;
   interface Wire#(Bit#(3)) arprot;
   interface Wire#(Bit#(4)) arqos;
   interface Wire#(Bit#(2)) arsize;
   interface Wire#(Bit#(1)) arvalid;
   interface Wire#(Bit#(addrWidth)) awaddr;
   interface Wire#(Bit#(2)) awburst;
   interface Wire#(Bit#(4)) awcache;
   interface Wire#(Bit#(tagWidth)) awid;
   interface Wire#(Bit#(4)) awlen;
   interface Wire#(Bit#(2)) awlock;
   interface Wire#(Bit#(3)) awprot;
   interface Wire#(Bit#(4)) awqos;
   interface Wire#(Bit#(2)) awsize;
   interface Wire#(Bit#(1)) awvalid;
   interface Wire#(Bit#(1)) rready;
   interface Wire#(Bit#(tagWidth)) wid;
   interface Wire#(Bit#(TDiv#(dataWidth,8))) wstrb;
   interface Wire#(Bit#(dataWidth)) wdata;
   interface Wire#(Bit#(1)) wlast;
   interface Wire#(Bit#(1)) wvalid;
   interface Wire#(Bit#(1)) bready;
endinterface

module mkAxiMasterWires(AxiMasterWires#(addrWidth, dataWidth, tagWidth));
   Vector#(6, Wire#(Bit#(1))) wires <- replicateM(mkDWire(0));
   Vector#(1, Wire#(Bit#(dataWidth))) datawires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(tagWidth))) idwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(2))) respwires <- 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 rid  = idwires[0];
   interface Wire rresp  = respwires[0];
   interface Wire rdata  = datawires[0];
   interface Wire rlast  = wires[4];
   interface Wire bvalid = wires[5];
   interface Wire bid    = idwires[1];
   interface Wire bresp  = respwires[1];
endmodule

module mkAxiSlaveWires(AxiSlaveWires#(addrWidth, dataWidth, tagWidth));
   Vector#(5, Wire#(Bit#(1))) wires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(addrWidth))) addrwires <- replicateM(mkDWire(0));
   Vector#(1, Wire#(Bit#(dataWidth))) datawires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(2))) burstwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(4))) cachewires <- replicateM(mkDWire(0));
   Vector#(3, Wire#(Bit#(tagWidth))) idwires <- replicateM(mkDWire(0));
   Vector#(1, Wire#(Bit#(TDiv#(dataWidth,8)))) strbwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(4))) lenwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(2))) lockwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(3))) protwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(4))) qoswires <- replicateM(mkDWire(0));
   Vector#(3, Wire#(Bit#(1))) validwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(2))) sizewires <- replicateM(mkDWire(0));
   Vector#(3, Wire#(Bit#(1))) readywires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(5))) userwires <- replicateM(mkDWire(0));
   Vector#(1, Wire#(Bit#(1))) lastwires <- replicateM(mkDWire(0));
   interface Wire araddr = addrwires[0];
   interface Wire arburst = burstwires[0];
   interface Wire arcache = cachewires[0];
   interface Wire arid = idwires[0];
   interface Wire arlen = lenwires[0];
   interface Wire arlock = lockwires[0];
   interface Wire arprot = protwires[0];
   interface Wire arqos = qoswires[0];
   interface Wire arsize = sizewires[0];
   interface Wire arvalid = validwires[0];

   interface Wire awaddr = addrwires[1];
   interface Wire awburst = burstwires[1];
   interface Wire awcache = cachewires[1];
   interface Wire awid = idwires[1];
   interface Wire awlen = lenwires[1];
   interface Wire awlock = lockwires[1];
   interface Wire awprot = protwires[1];
   interface Wire awqos = qoswires[1];
   interface Wire awsize = sizewires[1];
   interface Wire awvalid = validwires[1];

   interface Wire rready = readywires[0];
   interface Wire wid = idwires[2];
   interface Wire wstrb = strbwires[0];
   interface Wire wdata = datawires[0];
   interface Wire wlast = lastwires[0];
   interface Wire wvalid = validwires[2];
   interface Wire bready = readywires[1];
endmodule

module mkAxi3MasterGather#(AxiMasterBits#(addrWidth, dataWidth, tagWidth, Empty) axiWires)(AxiMasterCommon#(addrWidth, dataWidth, tagWidth));
//provisos(Div#(dataWidth, 8, 4));
   AxiMasterWires#(addrWidth, dataWidth, tagWidth) vtopmw <- mkAxiMasterWires;
   rule handshake1;
        axiWires.arready(vtopmw.arready);
   endrule
   rule handshake2;
        axiWires.awready(vtopmw.awready);
   endrule
   rule handshake3;
        axiWires.rid(vtopmw.rid);
        axiWires.rresp(vtopmw.rresp);
        axiWires.rdata(vtopmw.rdata);
        axiWires.rlast(vtopmw.rlast);
        axiWires.rvalid(vtopmw.rvalid);
   endrule
   rule handshake4;
        axiWires.wready(vtopmw.wready);
   endrule
   rule handshake5;
        axiWires.bvalid(vtopmw.bvalid);
        axiWires.bid(vtopmw.bid);
        axiWires.bresp(vtopmw.bresp);
   endrule

   interface Axi3Master client;
        interface Get req_ar;
             method ActionValue#(Axi3ReadRequest#(addrWidth,tagWidth)) get() if (axiWires.arvalid() != 0);
                 Axi3ReadRequest#(addrWidth,tagWidth) v;
                 v.address = axiWires.araddr();
                 v.burst = axiWires.arburst();
                 v.cache = axiWires.arcache();
                 v.id = axiWires.arid();
                 v.len = axiWires.arlen();
                 v.lock = axiWires.arlock();
                 v.prot = axiWires.arprot();
                 v.qos = axiWires.arqos();
                 v.size = {0, axiWires.arsize()};

                vtopmw.arready <= 1;
                return v;
            endmethod
        endinterface
        interface Get req_aw;
            method ActionValue#(Axi3WriteRequest#(addrWidth,tagWidth)) get() if (axiWires.awvalid() != 0);
                Axi3WriteRequest#(addrWidth,tagWidth) v;
                v.address = axiWires.awaddr();
                v.burst = axiWires.awburst();
                v.cache = axiWires.awcache();
                v.id = axiWires.awid();
                v.len = axiWires.awlen();
                v.lock = axiWires.awlock();
                v.prot = axiWires.awprot();
                v.qos = axiWires.awqos();
                v.size = {0, axiWires.awsize()};

                vtopmw.awready <= 1;
                return v;
           endmethod
        endinterface
        interface Put resp_read;
            method Action put(Axi3ReadResponse#(dataWidth, tagWidth) v) if (axiWires.rready() != 0);
                vtopmw.rid <= v.id;
                vtopmw.rresp <= v.resp;
                vtopmw.rdata <= v.data;
                vtopmw.rlast <= v.last;
                vtopmw.rvalid <= 1;
            endmethod
        endinterface
        interface Get resp_write;
            method ActionValue#(Axi3WriteData#(dataWidth,tagWidth)) get() if (axiWires.wvalid() != 0);
                Axi3WriteData#(dataWidth,tagWidth) v;
                v.id = axiWires.wid();
                v.byteEnable = axiWires.wstrb();
                v.data = axiWires.wdata();
                v.last = axiWires.wlast();

                vtopmw.wready <= 1;
                return v;
            endmethod
        endinterface
        interface Put resp_b;
            method Action put(Axi3WriteResponse#(tagWidth) v) if (axiWires.bready() != 0);
                vtopmw.bvalid <= 1;
                vtopmw.bid    <= v.id;
                vtopmw.bresp  <= v.resp;
            endmethod
        endinterface
    endinterface
    method aresetn = axiWires.aresetn;
endmodule

module mkAxi3SlaveGather#(AxiSlaveBits#(addrWidth, dataWidth, tagWidth,
    extraType) axiWires)(AxiSlaveCommon#(addrWidth, dataWidth,tagWidth,extraType));
    AxiSlaveWires#(addrWidth,dataWidth,tagWidth) vtopsw <- mkAxiSlaveWires;
    rule handshake1;
          axiWires.araddr(vtopsw.araddr);
          axiWires.arburst(vtopsw.arburst);
          axiWires.arcache(vtopsw.arcache);
          axiWires.arid(vtopsw.arid);
          axiWires.arlen(vtopsw.arlen);
          axiWires.arlock(vtopsw.arlock);
          axiWires.arprot(vtopsw.arprot);
          axiWires.arqos(vtopsw.arqos);
          axiWires.arsize(vtopsw.arsize);
          axiWires.arvalid(vtopsw.arvalid);
    endrule
    rule handshake2;
          axiWires.awaddr(vtopsw.awaddr);
          axiWires.awburst(vtopsw.awburst);
          axiWires.awcache(vtopsw.awcache);
          axiWires.awid(vtopsw.awid);
          axiWires.awlen(vtopsw.awlen);
          axiWires.awlock(vtopsw.awlock);
          axiWires.awprot(vtopsw.awprot);
          axiWires.awqos(vtopsw.awqos);
          axiWires.awsize(vtopsw.awsize);
          axiWires.awvalid(vtopsw.awvalid);
    endrule
    rule handshake3;
         axiWires.rready(vtopsw.rready);
    endrule
    rule handshake4;
          axiWires.wid(vtopsw.wid);
          axiWires.wstrb(vtopsw.wstrb);
          axiWires.wdata(vtopsw.wdata);
          axiWires.wlast(vtopsw.wlast);
          axiWires.wvalid(vtopsw.wvalid);
    endrule
    rule handshake5;
         axiWires.bready(vtopsw.bready);
    endrule
    interface Axi3Slave server;
    interface Put req_ar;
        method Action put(Axi3ReadRequest#(addrWidth,tagWidth) v) if (axiWires.arready() != 0);
           vtopsw.araddr <= v.address;
           vtopsw.arburst <= v.burst;
           vtopsw.arcache <= v.cache;
           vtopsw.arid <= v.id;
           vtopsw.arlen <= v.len;
           vtopsw.arlock <= v.lock;
           vtopsw.arprot <= v.prot;
           vtopsw.arqos <= v.qos;
           vtopsw.arsize <= v.size[1:0];

           vtopsw.arvalid <= 1;
        endmethod
    endinterface
    interface Put req_aw;
        method Action put(Axi3WriteRequest#(addrWidth,tagWidth) v) if (axiWires.awready() != 0);
           vtopsw.awaddr <= v.address;
           vtopsw.awburst <= v.burst;
           vtopsw.awcache <= v.cache;
           vtopsw.awid <= v.id;
           vtopsw.awlen <= v.len;
           vtopsw.awlock <= v.lock;
           vtopsw.awprot <= v.prot;
           vtopsw.awqos <= v.qos;
           vtopsw.awsize <= v.size[1:0];

           vtopsw.awvalid <= 1;
        endmethod
    endinterface
    interface Put resp_write;
        method Action put(Axi3WriteData#(dataWidth,tagWidth) v) if (axiWires.wready() != 0);
           vtopsw.wid <= v.id;
           vtopsw.wstrb <= v.byteEnable;
           vtopsw.wdata <= v.data;
           vtopsw.wlast <= v.last;

           vtopsw.wvalid <= 1;
        endmethod
    endinterface
    interface Get resp_read;
        method ActionValue#(Axi3ReadResponse#(dataWidth, tagWidth)) get() if (axiWires.rvalid() != 0);
            Axi3ReadResponse#(dataWidth, tagWidth) v;
            v.id = axiWires.rid();
            v.resp = axiWires.rresp();
            v.data = axiWires.rdata();
            v.last = axiWires.rlast();

            vtopsw.rready <= 1;
            return v;
        endmethod
         endinterface
    interface Get resp_b;
        method ActionValue#(Axi3WriteResponse#(tagWidth)) get() if (axiWires.bvalid() != 0);
            Axi3WriteResponse#(tagWidth) v;
            v.id = axiWires.bid();
            v.resp = axiWires.bresp();

            vtopsw.bready <= 1;
            return v;
        endmethod
     endinterface
     endinterface
     interface extra = axiWires.extra;
     method aresetn = axiWires.aresetn;
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 GetPut::*;
import Vector::*;
import PPS7LIB::*;
import AxiMasterSlave::*;
import AxiBits::*;

interface AxiMasterCommon#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth);
    method Bit#(1)            aresetn();
    interface Axi3Master#(addrWidth,dataWidth,tagWidth) client;
endinterface

interface AxiSlaveCommon#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth, type extraType);
    method Bit#(1)            aresetn();
    interface Axi3Slave#(addrWidth,dataWidth,tagWidth) server;
    interface extraType   extra;
endinterface

interface AxiMasterWires#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth);
   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;

   interface Wire#(Bit#(tagWidth)) rid;
   interface Wire#(Bit#(2))  rresp;
   interface Wire#(Bit#(dataWidth)) rdata;
   interface Wire#(Bit#(1))  rlast;
   interface Wire#(Bit#(tagWidth)) bid;
   interface Wire#(Bit#(2)) bresp;
endinterface

interface AxiSlaveWires#(numeric type addrWidth, numeric type dataWidth, numeric type tagWidth);
   interface Wire#(Bit#(addrWidth)) araddr;
   interface Wire#(Bit#(2)) arburst;
   interface Wire#(Bit#(4)) arcache;
   interface Wire#(Bit#(tagWidth)) arid;
   interface Wire#(Bit#(4)) arlen;
   interface Wire#(Bit#(2)) arlock;
   interface Wire#(Bit#(3)) arprot;
   interface Wire#(Bit#(4)) arqos;
   interface Wire#(Bit#(2)) arsize;
   interface Wire#(Bit#(1)) arvalid;
   interface Wire#(Bit#(addrWidth)) awaddr;
   interface Wire#(Bit#(2)) awburst;
   interface Wire#(Bit#(4)) awcache;
   interface Wire#(Bit#(tagWidth)) awid;
   interface Wire#(Bit#(4)) awlen;
   interface Wire#(Bit#(2)) awlock;
   interface Wire#(Bit#(3)) awprot;
   interface Wire#(Bit#(4)) awqos;
   interface Wire#(Bit#(2)) awsize;
   interface Wire#(Bit#(1)) awvalid;
   interface Wire#(Bit#(1)) rready;
   interface Wire#(Bit#(tagWidth)) wid;
   interface Wire#(Bit#(TDiv#(dataWidth,8))) wstrb;
   interface Wire#(Bit#(dataWidth)) wdata;
   interface Wire#(Bit#(1)) wlast;
   interface Wire#(Bit#(1)) wvalid;
   interface Wire#(Bit#(1)) bready;
endinterface

module mkAxiMasterWires(AxiMasterWires#(addrWidth, dataWidth, tagWidth));
   Vector#(6, Wire#(Bit#(1))) wires <- replicateM(mkDWire(0));
   Vector#(1, Wire#(Bit#(dataWidth))) datawires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(tagWidth))) idwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(2))) respwires <- 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 rid  = idwires[0];
   interface Wire rresp  = respwires[0];
   interface Wire rdata  = datawires[0];
   interface Wire rlast  = wires[4];
   interface Wire bvalid = wires[5];
   interface Wire bid    = idwires[1];
   interface Wire bresp  = respwires[1];
endmodule

module mkAxiSlaveWires(AxiSlaveWires#(addrWidth, dataWidth, tagWidth));
   Vector#(5, Wire#(Bit#(1))) wires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(addrWidth))) addrwires <- replicateM(mkDWire(0));
   Vector#(1, Wire#(Bit#(dataWidth))) datawires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(2))) burstwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(4))) cachewires <- replicateM(mkDWire(0));
   Vector#(3, Wire#(Bit#(tagWidth))) idwires <- replicateM(mkDWire(0));
   Vector#(1, Wire#(Bit#(TDiv#(dataWidth,8)))) strbwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(4))) lenwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(2))) lockwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(3))) protwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(4))) qoswires <- replicateM(mkDWire(0));
   Vector#(3, Wire#(Bit#(1))) validwires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(2))) sizewires <- replicateM(mkDWire(0));
   Vector#(3, Wire#(Bit#(1))) readywires <- replicateM(mkDWire(0));
   Vector#(2, Wire#(Bit#(5))) userwires <- replicateM(mkDWire(0));
   Vector#(1, Wire#(Bit#(1))) lastwires <- replicateM(mkDWire(0));
   interface Wire araddr = addrwires[0];
   interface Wire arburst = burstwires[0];
   interface Wire arcache = cachewires[0];
   interface Wire arid = idwires[0];
   interface Wire arlen = lenwires[0];
   interface Wire arlock = lockwires[0];
   interface Wire arprot = protwires[0];
   interface Wire arqos = qoswires[0];
   interface Wire arsize = sizewires[0];
   interface Wire arvalid = validwires[0];

   interface Wire awaddr = addrwires[1];
   interface Wire awburst = burstwires[1];
   interface Wire awcache = cachewires[1];
   interface Wire awid = idwires[1];
   interface Wire awlen = lenwires[1];
   interface Wire awlock = lockwires[1];
   interface Wire awprot = protwires[1];
   interface Wire awqos = qoswires[1];
   interface Wire awsize = sizewires[1];
   interface Wire awvalid = validwires[1];

   interface Wire rready = readywires[0];
   interface Wire wid = idwires[2];
   interface Wire wstrb = strbwires[0];
   interface Wire wdata = datawires[0];
   interface Wire wlast = lastwires[0];
   interface Wire wvalid = validwires[2];
   interface Wire bready = readywires[1];
endmodule

module mkAxi3MasterGather#(AxiMasterBits#(addrWidth, dataWidth, tagWidth, Empty) axiWires)(AxiMasterCommon#(addrWidth, dataWidth, tagWidth))
provisos(Div#(dataWidth, 8, 4));
   AxiMasterWires#(addrWidth, dataWidth, tagWidth) vtopmw <- mkAxiMasterWires;
   rule handshake1;
        axiWires.arready(vtopmw.arready);
   endrule
   rule handshake2;
        axiWires.awready(vtopmw.awready);
   endrule
   rule handshake3;
        axiWires.rid(vtopmw.rid);
        axiWires.rresp(vtopmw.rresp);
        axiWires.rdata(vtopmw.rdata);
        axiWires.rlast(vtopmw.rlast);
        axiWires.rvalid(vtopmw.rvalid);
   endrule
   rule handshake4;
        axiWires.wready(vtopmw.wready);
   endrule
   rule handshake5;
        axiWires.bvalid(vtopmw.bvalid);
        axiWires.bid(vtopmw.bid);
        axiWires.bresp(vtopmw.bresp);
   endrule

   interface Axi3Master client;
        interface Get req_ar;
             method ActionValue#(Axi3ReadRequest#(addrWidth,tagWidth)) get() if (axiWires.arvalid() != 0);
                 Axi3ReadRequest#(addrWidth,tagWidth) v;
                 v.address = axiWires.araddr();
                 v.burst = axiWires.arburst();
                 v.cache = axiWires.arcache();
                 v.id = axiWires.arid();
                 v.len = axiWires.arlen();
                 v.lock = axiWires.arlock();
                 v.prot = axiWires.arprot();
                 v.qos = axiWires.arqos();
                 v.size = {0, axiWires.arsize()};

                vtopmw.arready <= 1;
                return v;
            endmethod
        endinterface
        interface Get req_aw;
            method ActionValue#(Axi3WriteRequest#(addrWidth,tagWidth)) get() if (axiWires.awvalid() != 0);
                Axi3WriteRequest#(addrWidth,tagWidth) v;
                v.address = axiWires.awaddr();
                v.burst = axiWires.awburst();
                v.cache = axiWires.awcache();
                v.id = axiWires.awid();
                v.len = axiWires.awlen();
                v.lock = axiWires.awlock();
                v.prot = axiWires.awprot();
                v.qos = axiWires.awqos();
                v.size = {0, axiWires.awsize()};

                vtopmw.awready <= 1;
                return v;
           endmethod
        endinterface
        interface Put resp_read;
            method Action put(Axi3ReadResponse#(dataWidth, tagWidth) v) if (axiWires.rready() != 0);
                vtopmw.rid <= v.id;
                vtopmw.rresp <= v.resp;
                vtopmw.rdata <= v.data;
                vtopmw.rlast <= v.last;
                vtopmw.rvalid <= 1;
            endmethod
        endinterface
        interface Get resp_write;
            method ActionValue#(Axi3WriteData#(dataWidth,tagWidth)) get() if (axiWires.wvalid() != 0);
                Axi3WriteData#(dataWidth,tagWidth) v;
                v.id = axiWires.wid();
                v.byteEnable = axiWires.wstrb();
                v.data = axiWires.wdata();
                v.last = axiWires.wlast();

                vtopmw.wready <= 1;
                return v;
            endmethod
        endinterface
        interface Put resp_b;
            method Action put(Axi3WriteResponse#(tagWidth) v) if (axiWires.bready() != 0);
                vtopmw.bvalid <= 1;
                vtopmw.bid    <= v.id;
                vtopmw.bresp  <= v.resp;
            endmethod
        endinterface
    endinterface
    method aresetn = axiWires.aresetn;
endmodule

module mkAxi3SlaveGather#(AxiSlaveBits#(addrWidth, dataWidth, tagWidth,
    extraType) axiWires)(AxiSlaveCommon#(addrWidth, dataWidth,tagWidth,extraType));
    AxiSlaveWires#(addrWidth,dataWidth,tagWidth) vtopsw <- mkAxiSlaveWires;
    rule handshake1;
          axiWires.araddr(vtopsw.araddr);
          axiWires.arburst(vtopsw.arburst);
          axiWires.arcache(vtopsw.arcache);
          axiWires.arid(vtopsw.arid);
          axiWires.arlen(vtopsw.arlen);
          axiWires.arlock(vtopsw.arlock);
          axiWires.arprot(vtopsw.arprot);
          axiWires.arqos(vtopsw.arqos);
          axiWires.arsize(vtopsw.arsize);
          axiWires.arvalid(vtopsw.arvalid);
    endrule
    rule handshake2;
          axiWires.awaddr(vtopsw.awaddr);
          axiWires.awburst(vtopsw.awburst);
          axiWires.awcache(vtopsw.awcache);
          axiWires.awid(vtopsw.awid);
          axiWires.awlen(vtopsw.awlen);
          axiWires.awlock(vtopsw.awlock);
          axiWires.awprot(vtopsw.awprot);
          axiWires.awqos(vtopsw.awqos);
          axiWires.awsize(vtopsw.awsize);
          axiWires.awvalid(vtopsw.awvalid);
    endrule
    rule handshake3;
         axiWires.rready(vtopsw.rready);
    endrule
    rule handshake4;
          axiWires.wid(vtopsw.wid);
          axiWires.wstrb(vtopsw.wstrb);
          axiWires.wdata(vtopsw.wdata);
          axiWires.wlast(vtopsw.wlast);
          axiWires.wvalid(vtopsw.wvalid);
    endrule
    rule handshake5;
         axiWires.bready(vtopsw.bready);
    endrule
    interface Axi3Slave server;
    interface Put req_ar;
        method Action put(Axi3ReadRequest#(addrWidth,tagWidth) v) if (axiWires.arready() != 0);
           vtopsw.araddr <= v.address;
           vtopsw.arburst <= v.burst;
           vtopsw.arcache <= v.cache;
           vtopsw.arid <= v.id;
           vtopsw.arlen <= v.len;
           vtopsw.arlock <= v.lock;
           vtopsw.arprot <= v.prot;
           vtopsw.arqos <= v.qos;
           vtopsw.arsize <= v.size[1:0];

           vtopsw.arvalid <= 1;
        endmethod
    endinterface
    interface Put req_aw;
        method Action put(Axi3WriteRequest#(addrWidth,tagWidth) v) if (axiWires.awready() != 0);
           vtopsw.awaddr <= v.address;
           vtopsw.awburst <= v.burst;
           vtopsw.awcache <= v.cache;
           vtopsw.awid <= v.id;
           vtopsw.awlen <= v.len;
           vtopsw.awlock <= v.lock;
           vtopsw.awprot <= v.prot;
           vtopsw.awqos <= v.qos;
           vtopsw.awsize <= v.size[1:0];

           vtopsw.awvalid <= 1;
        endmethod
    endinterface
    interface Put resp_write;
        method Action put(Axi3WriteData#(dataWidth,tagWidth) v) if (axiWires.wready() != 0);
           vtopsw.wid <= v.id;
           vtopsw.wstrb <= v.byteEnable;
           vtopsw.wdata <= v.data;
           vtopsw.wlast <= v.last;

           vtopsw.wvalid <= 1;
        endmethod
    endinterface
    interface Get resp_read;
        method ActionValue#(Axi3ReadResponse#(dataWidth, tagWidth)) get() if (axiWires.rvalid() != 0);
            Axi3ReadResponse#(dataWidth, tagWidth) v;
            v.id = axiWires.rid();
            v.resp = axiWires.rresp();
            v.data = axiWires.rdata();
            v.last = axiWires.rlast();

            vtopsw.rready <= 1;
            return v;
        endmethod
         endinterface
    interface Get resp_b;
        method ActionValue#(Axi3WriteResponse#(tagWidth)) get() if (axiWires.bvalid() != 0);
            Axi3WriteResponse#(tagWidth) v;
            v.id = axiWires.bid();
            v.resp = axiWires.bresp();

            vtopsw.bready <= 1;
            return v;
        endmethod
     endinterface
     endinterface
     interface extra = axiWires.extra;
     method aresetn = axiWires.aresetn;
endmodule


Removed references to impCondOf in FIFOG

// Copyright (c) 2016, 2017 Massachusetts Institute of Technology

// 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 package contains constructors for a group of FIFOs with a `FIFOG`
 * interface. `FIFOG` is like `FIFOF`, but instead of adding information
 * about the fullness of the FIFO, it adds information about the guards
 * of the FIFO.
 *
 * In a correct `FIFOF` implementation, `notFull` and `notEmpty` must be
 * scheduled before both `enq` and `deq` for correct one-rule-at-a-time
 * semantics. In this case, the following two rules conflict and are unable to
 * be scheduled in the same cycle.
 *
 * ```
 * rule enqIntoFIFOF;
 *     if (fifo.notFull) fifo.enq(x);
 * endrule
 *
 * rule deqFromFIFOF;
 *     if (fifo.notEmpty) fifo.deq();
 * endrule
 * ```
 *
 * Semantically, the interface method `canEnq` does not have to come before
 * `deq`, and `canDeq` do not have to come before `enq`, so by using `FIFOG`
 * you can write the two rules below which will not conflict.
 *
 * ```
 * rule enqIntoFIFOG;
 *     if (fifo.canEnq) fifo.enq(x);
 * endrule
 *
 * rule deqFromFIFOG;
 *     if (fifo.canDeq) fifo.deq();
 * endrule
 * ```
 *
 */
package FIFOG;

import FIFOF::*;
import GetPut::*;
import SpecialFIFOs::*;
import RevertingVirtualReg::*;

export FIFOG(..);
export mkFIFOG;
export mkSizedFIFOG;
export mkFIFOG1;
export mkLFIFOG;
export mkBypassFIFOG;
export mkPipelineFIFOG;

/// Like FIFOF, but instead of adding information about the full-ness of the
/// FIFO, it adds information about the guard of the FIFO.
interface FIFOG#(type t);
    method Action enq(t x);
    method Action deq;
    method t first;
    method Action clear;
    method Bool notFull;
    method Bool notEmpty;
    method Bool canEnq;
    method Bool canDeq;
endinterface

// toGet and toPut functions for FIFOG interface
instance ToGet#(FIFOG#(t), t);
    function Get#(t) toGet(FIFOG#(t) m);
        return (interface Get;
                    method ActionValue#(t) get();
                        m.deq;
                        return m.first();
                    endmethod
                endinterface);
    endfunction
endinstance

instance ToPut#(FIFOG#(t), t);
    function Put#(t) toPut(FIFOG#(t) m);
        return (interface Put;
                    method Action put(t x);
                        m.enq(x);
                    endmethod
                endinterface);
    endfunction
endinstance

// FIFOG versions of FIFOF package

/// 2-element conflict-free `FIFOG`
module mkFIFOG(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkFIFOF);
    return _m;
endmodule

/// Sized conflict-free `FIFOG`
module mkSizedFIFOG#(Integer n)(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkSizedFIFOF(n));
    return _m;
endmodule

/// 1-element conflicting `FIFOG`
module mkFIFOG1(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkFIFOF1);
    return _m;
endmodule

/// Pipeline `FIFOG`
module mkLFIFOG(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkLFIFOF);
    return _m;
endmodule

// not included: mkGFIFO*, mkUGFIFO*, and mkDepthParamFIFOG

/////////////////////////////////////
// FIFOG versions of FIFOF package //
/////////////////////////////////////

/// Bypass `FIFOG`
///
/// Note: `mkSizedBypassFIFOF` isn't correct, so we don't expose a
/// `mkSizedBypassFIFOG` (its `notEmpty` and `notFull` methods are CF with
/// `enq` and `deq`, but semantically that is not possible with
/// one-rule-at-a-time semantics.)
module mkBypassFIFOG(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkBypassFIFOF);
    return _m;
endmodule

/// Pipeline `FIFOG`
///
/// This FIFO has a scheduling constraint that requires `deq` to come before
/// `enq`.
module mkPipelineFIFOG(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkPipelineFIFOF);
    return _m;
endmodule

/// Module to make `FIFOG` from a `FIFOF` module.
///
/// This module construct a `FIFOG` from a `FIFOF` by using wires to delay the
/// the `notEmpty` and `notFull` signals so they can be used as `canDeq` and `canEnq`.
module [m] mkFIFOGfromFIFOF#(m#(FIFOF#(t)) mkM)(FIFOG#(t)) provisos (Bits#(t,tSz), IsModule#(m, a__));
    (* hide *)
    FIFOF#(t) _m <- mkM;

    Wire#(Bool) canEnq_wire <- mkBypassWire;
    Wire#(Bool) canDeq_wire <- mkBypassWire;
    // virtual regs are only used to force SB ordering between methods
    Reg#(Bool) virtualEnqReg <- mkRevertingVirtualReg(True);
    Reg#(Bool) virtualDeqReg <- mkRevertingVirtualReg(True);

    (* fire_when_enabled *)
    rule setCanEnqWire;
        canEnq_wire <= _m.notFull;
    endrule
    (* fire_when_enabled *)
    rule setCanDeqWire;
        canDeq_wire <= _m.notEmpty;
    endrule

    // These rules can help with debugging when using this module on a new
    // FIFOF module, but they are commented out in normal use because
    // impCondOf() is not fully supported by the bluespec compiler yet and
    // causes compilation warnings.
    // rule doAssert1;
    //     if (canEnq_wire != impCondOf(_m.enq)) begin
    //         $fdisplay(stderr, "[ERROR] mkFIFOGfromFIFOF: canEnq_wire != impCondOf(_m.enq)");
    //     end
    // endrule
    // rule doAssert2;
    //     if (canDeq_wire != impCondOf(_m.deq)) begin
    //         $fdisplay(stderr, "[ERROR] mkFIFOGfromFIFOF: canDeq_wire != impCondOf(_m.deq)");
    //     end
    // endrule

    method Action enq(t x);
        _m.enq(x);
        virtualEnqReg <= False;
    endmethod
    method Action deq;
        _m.deq;
        virtualDeqReg <= False;
    endmethod
    method t first = _m.first;
    method Action clear = _m.clear;
    method Bool notFull = _m.notFull;
    method Bool notEmpty = _m.notEmpty;
    method Bool canEnq if (virtualEnqReg) = canEnq_wire;
    method Bool canDeq if (virtualDeqReg) = canDeq_wire;
endmodule

endpackage

// Copyright (c) 2016, 2017 Massachusetts Institute of Technology

// 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 package contains constructors for a group of FIFOs with a `FIFOG`
 * interface. `FIFOG` is like `FIFOF`, but instead of adding information
 * about the fullness of the FIFO, it adds information about the guards
 * of the FIFO.
 *
 * In a correct `FIFOF` implementation, `notFull` and `notEmpty` must be
 * scheduled before both `enq` and `deq` for correct one-rule-at-a-time
 * semantics. In this case, the following two rules conflict and are unable to
 * be scheduled in the same cycle.
 *
 * ```
 * rule enqIntoFIFOF;
 *     if (fifo.notFull) fifo.enq(x);
 * endrule
 *
 * rule deqFromFIFOF;
 *     if (fifo.notEmpty) fifo.deq();
 * endrule
 * ```
 *
 * Semantically, the interface method `canEnq` does not have to come before
 * `deq`, and `canDeq` do not have to come before `enq`, so by using `FIFOG`
 * you can write the two rules below which will not conflict.
 *
 * ```
 * rule enqIntoFIFOG;
 *     if (fifo.canEnq) fifo.enq(x);
 * endrule
 *
 * rule deqFromFIFOG;
 *     if (fifo.canDeq) fifo.deq();
 * endrule
 * ```
 *
 */
package FIFOG;

import FIFOF::*;
import GetPut::*;
import SpecialFIFOs::*;
import RevertingVirtualReg::*;

export FIFOG(..);
export mkFIFOG;
export mkSizedFIFOG;
export mkFIFOG1;
export mkLFIFOG;
export mkBypassFIFOG;
export mkPipelineFIFOG;

/// Like FIFOF, but instead of adding information about the full-ness of the
/// FIFO, it adds information about the guard of the FIFO.
interface FIFOG#(type t);
    method Action enq(t x);
    method Action deq;
    method t first;
    method Action clear;
    method Bool notFull;
    method Bool notEmpty;
    method Bool canEnq;
    method Bool canDeq;
endinterface

// toGet and toPut functions for FIFOG interface
instance ToGet#(FIFOG#(t), t);
    function Get#(t) toGet(FIFOG#(t) m);
        return (interface Get;
                    method ActionValue#(t) get();
                        m.deq;
                        return m.first();
                    endmethod
                endinterface);
    endfunction
endinstance

instance ToPut#(FIFOG#(t), t);
    function Put#(t) toPut(FIFOG#(t) m);
        return (interface Put;
                    method Action put(t x);
                        m.enq(x);
                    endmethod
                endinterface);
    endfunction
endinstance

// FIFOG versions of FIFOF package

/// 2-element conflict-free `FIFOG`
module mkFIFOG(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkFIFOF);
    return _m;
endmodule

/// Sized conflict-free `FIFOG`
module mkSizedFIFOG#(Integer n)(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkSizedFIFOF(n));
    return _m;
endmodule

/// 1-element conflicting `FIFOG`
module mkFIFOG1(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkFIFOF1);
    return _m;
endmodule

/// Pipeline `FIFOG`
module mkLFIFOG(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkLFIFOF);
    return _m;
endmodule

// not included: mkGFIFO*, mkUGFIFO*, and mkDepthParamFIFOG

/////////////////////////////////////
// FIFOG versions of FIFOF package //
/////////////////////////////////////

/// Bypass `FIFOG`
///
/// Note: `mkSizedBypassFIFOF` isn't correct, so we don't expose a
/// `mkSizedBypassFIFOG` (its `notEmpty` and `notFull` methods are CF with
/// `enq` and `deq`, but semantically that is not possible with
/// one-rule-at-a-time semantics.)
module mkBypassFIFOG(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkBypassFIFOF);
    return _m;
endmodule

/// Pipeline `FIFOG`
///
/// This FIFO has a scheduling constraint that requires `deq` to come before
/// `enq`.
module mkPipelineFIFOG(FIFOG#(t)) provisos (Bits#(t,tSz));
    (* hide *)
    let _m <- mkFIFOGfromFIFOF(mkPipelineFIFOF);
    return _m;
endmodule

/// Module to make `FIFOG` from a `FIFOF` module.
///
/// This module construct a `FIFOG` from a `FIFOF` by using wires to delay the
/// the `notEmpty` and `notFull` signals so they can be used as `canDeq` and `canEnq`.
module [m] mkFIFOGfromFIFOF#(m#(FIFOF#(t)) mkM)(FIFOG#(t)) provisos (Bits#(t,tSz), IsModule#(m, a__));
    (* hide *)
    FIFOF#(t) _m <- mkM;

    Wire#(Bool) canEnq_wire <- mkBypassWire;
    Wire#(Bool) canDeq_wire <- mkBypassWire;
    // virtual regs are only used to force SB ordering between methods
    Reg#(Bool) virtualEnqReg <- mkRevertingVirtualReg(True);
    Reg#(Bool) virtualDeqReg <- mkRevertingVirtualReg(True);

    (* fire_when_enabled *)
    rule setCanEnqWire;
        canEnq_wire <= _m.notFull;
    endrule
    (* fire_when_enabled *)
    rule setCanDeqWire;
        canDeq_wire <= _m.notEmpty;
    endrule

    rule doAssert1;
        if (canEnq_wire != impCondOf(_m.enq)) begin
            $fdisplay(stderr, "[ERROR] mkFIFOGfromFIFOF: canEnq_wire != impCondOf(_m.enq)");
        end
    endrule
    rule doAssert2;
        if (canDeq_wire != impCondOf(_m.deq)) begin
            $fdisplay(stderr, "[ERROR] mkFIFOGfromFIFOF: canDeq_wire != impCondOf(_m.deq)");
        end
    endrule

    method Action enq(t x);
        _m.enq(x);
        virtualEnqReg <= False;
    endmethod
    method Action deq;
        _m.deq;
        virtualDeqReg <= False;
    endmethod
    method t first = _m.first;
    method Action clear = _m.clear;
    method Bool notFull = _m.notFull;
    method Bool notEmpty = _m.notEmpty;
    method Bool canEnq if (virtualEnqReg) = canEnq_wire;
    method Bool canDeq if (virtualDeqReg) = canDeq_wire;
endmodule

endpackage