more elink conversion

more elink conversion

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

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

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

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

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

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

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

(* always_ready, always_enabled *)
interface Par_rx;
   method Bit#(8) data_p();
   method Bit#(8) data_n();
   method Bit#(1) frame_p();
   method Bit#(1) frame_n();
   method Bit#(1) lclk_p();
   method Bit#(1) lclk_n();
   method Action wr_wait_p(Bit#(1) v);
   method Action wr_wait_n(Bit#(1) v);
   method Action rd_wait_p(Bit#(1) v);
   method Action rd_wait_n(Bit#(1) v);
endinterface

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

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

(* always_ready, always_enabled *)
interface PParallellaLIB;
   interface Par_tx tx;
   interface Par_rx rx;
   interface ParMaxiGp maxi;   // this will connect to a master
   interface ParSaxiHp saxi;  // this will connect to a slave
   interface Par_misc misc;
endinterface

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

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

   interface Par_tx tx;
      method data_p(tx_data_p) enable((*inhigh*) EN_tx_data_p);
      method data_n(tx_data_n) enable((*inhigh*) EN_tx_data_n);
      method frame_p(tx_frame_p) enable((*inhigh*) EN_tx_frame_p);
      method frame_n(tx_frame_n) enable((*inhigh*) EN_tx_frame_n);
      method lclk_p(tx_lclk_p) enable((*inhigh*) EN_tx_lclk_p);
      method lclk_n(tx_lclk_n) enable((*inhigh*) EN_tx_lclk_n);
      method tx_wr_wait_p wr_wait_p();
      method tx_wr_wait_n wr_wait_n();
      method tx_rd_wait_p rd_wait_p();
      method tx_rd_wait_n rd_wait_n();
   endinterface

   interface Par_rx rx;
      method rx_data_p data_p();
      method rx_data_n data_n();
      method rx_frame_p frame_p();
      method rx_frame_n frame_n();
      method rx_lclk_p lclk_p();
      method rx_lclk_n lclk_n();
      method wr_wait_p(rx_wr_wait_p) enable((*inhigh*) EN_rx_wr_wait_p);
      method wr_wait_n(rx_wr_wait_n) enable((*inhigh*) EN_rx_wr_wait_n);
      method rd_wait_p(rx_rd_wait_p) enable((*inhigh*) EN_rx_rd_wait_p);
      method rd_wait_n(rx_rd_wait_n) enable((*inhigh*) EN_rx_rd_wait_n);
   endinterface

   interface ParSaxiHp saxi;
      method s_axi_araddr araddr() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arburst arburst() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arcache arcache() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_aresetn aresetn() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arid arid() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arlen arlen() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arlock arlock() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arprot arprot() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arqos arqos() clocked_by (saxiclk) reset_by(saxireset);
      method arready(s_axi_arready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_arready);
      method s_axi_arsize arsize() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arvalid arvalid() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awaddr awaddr() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awburst awburst() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awcache awcache() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awid awid() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awlen awlen() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awlock awlock() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awprot awprot() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awqos awqos() clocked_by (saxiclk) reset_by(saxireset);
      method awready(s_axi_awready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_awready);
      method s_axi_awsize awsize() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awvalid awvalid() clocked_by (saxiclk) reset_by(saxireset);
      method bid(s_axi_bid) enable((*inhigh*) EN_s_axi_bid);
      method s_axi_bready bready() clocked_by (saxiclk) reset_by(saxireset);
      method bresp(s_axi_bresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_bresp);
      method bvalid(s_axi_bvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_bvalid);
      method rdata(s_axi_rdata)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rdata);
      method rid(s_axi_rid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rid);
      method rlast(s_axi_rlast)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rlast);
      method s_axi_rready rready() clocked_by (saxiclk) reset_by(saxireset);
      method rresp(s_axi_rresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rresp);
      method rvalid(s_axi_rvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rvalid);
      method s_axi_wdata wdata() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_wid wid() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_wlast wlast() clocked_by (saxiclk) reset_by(saxireset);
      method wready(s_axi_wready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_wready);
      method s_axi_wstrb wstrb() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_wvalid wvalid() clocked_by (saxiclk) reset_by(saxireset);
   endinterface

   interface ParMaxiGp maxi;
      method araddr(m_axi_araddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_araddr);
      method arburst(m_axi_arburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arburst);
      method arcache(m_axi_arcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arcache);
      method m_axi_aresetn aresetn() clocked_by(maxiclk) reset_by(maxireset);
      method arid(m_axi_arid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arid);
      method arlen(m_axi_arlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arlen);
      method arlock(m_axi_arlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arlock);
      method arprot(m_axi_arprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arprot);
      method arqos(m_axi_arqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arqos);
      method m_axi_arready arready() clocked_by(maxiclk) reset_by(maxireset);
      method arsize(m_axi_arsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arsize);
      method arvalid(m_axi_arvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arvalid);
      method awaddr(m_axi_awaddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awaddr);
      method awburst(m_axi_awburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awburst);
      method awcache(m_axi_awcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awcache);
      method awid(m_axi_awid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awid);
      method awlen(m_axi_awlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awlen);
      method awlock(m_axi_awlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awlock);
      method awprot(m_axi_awprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awprot);
      method awqos(m_axi_awqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awqos);
      method m_axi_awready awready() clocked_by(maxiclk) reset_by(maxireset);
      method awsize(m_axi_awsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awsize);
      method awvalid(m_axi_awvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awvalid);
      method m_axi_bid bid() clocked_by(maxiclk) reset_by(maxireset);
      method bready(m_axi_bready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_bready);
      method m_axi_bresp bresp() clocked_by(maxiclk) reset_by(maxireset);
      method m_axi_bvalid bvalid() clocked_by(maxiclk) reset_by(maxireset);
      method m_axi_rdata rdata() clocked_by(maxiclk) reset_by(maxireset);
      method m_axi_rlast rlast() clocked_by(maxiclk) reset_by(maxireset);
      method rready(m_axi_rready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_rready);
      method m_axi_rresp rresp() clocked_by(maxiclk) reset_by(maxireset);
      method m_axi_rvalid rvalid() clocked_by(maxiclk) reset_by(maxireset);
      method wdata(m_axi_wdata) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wdata);
      method wid(m_axi_wid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wid);
      method wlast(m_axi_wlast) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wlast);
      method m_axi_wready wready() clocked_by(maxiclk) reset_by(maxireset);
      method wstrb(m_axi_wstrb) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wstrb);
      method wvalid(m_axi_wvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wvalid);
      method m_axi_rid rid() clocked_by(maxiclk) reset_by(maxireset);
   endinterface

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

   );

endmodule

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

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

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

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

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

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

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

(* always_ready, always_enabled *)
interface Par_rx;
   method Bit#(8) data_p();
   method Bit#(8) data_n();
   method Bit#(1) frame_p();
   method Bit#(1) frame_n();
   method Bit#(1) lclk_p();
   method Bit#(1) lclk_n();
   method Action wr_wait_p(Bit#(1) v);
   method Action wr_wait_n(Bit#(1) v);
   method Action rd_wait_p(Bit#(1) v);
   method Action rd_wait_n(Bit#(1) v);
endinterface

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

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

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

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

   interface Par_misc misc;
      method csysack csysack();
      method cactive cactive();
      method reset_chip reset_chip();
      method reset_fpga reset_fpga();
      method csysreq(csysreq) enable((*inhigh*) EN_csysreq);
      method cclk_p(rxi_cclk_p) enable((*inhigh*) EN_rxi_cclk_p);
      method cclk_n(rxi_cclk_n) enable((*inhigh*) EN_rxi_cclk_n);
   endinterface

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

   interface Par_txi txi;
      method txo_wr_wait_p wr_wait_p();
      method txo_wr_wait_n wr_wait_n();
      method txo_rd_wait_p rd_wait_p();
      method txo_rd_wait_n rd_wait_n();
   endinterface

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

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

   interface ParSaxiHp saxi;
      method s_axi_araddr araddr() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arburst arburst() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arcache arcache() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_aresetn aresetn() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arid arid() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arlen arlen() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arlock arlock() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arprot arprot() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arqos arqos() clocked_by (saxiclk) reset_by(saxireset);
      method arready(s_axi_arready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_arready);
      method s_axi_arsize arsize() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_arvalid arvalid() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awaddr awaddr() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awburst awburst() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awcache awcache() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awid awid() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awlen awlen() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awlock awlock() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awprot awprot() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awqos awqos() clocked_by (saxiclk) reset_by(saxireset);
      method awready(s_axi_awready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_awready);
      method s_axi_awsize awsize() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_awvalid awvalid() clocked_by (saxiclk) reset_by(saxireset);
      method bid(s_axi_bid) enable((*inhigh*) EN_s_axi_bid);
      method s_axi_bready bready() clocked_by (saxiclk) reset_by(saxireset);
      method bresp(s_axi_bresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_bresp);
      method bvalid(s_axi_bvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_bvalid);
      method rdata(s_axi_rdata)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rdata);
      method rid(s_axi_rid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rid);
      method rlast(s_axi_rlast)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rlast);
      method s_axi_rready rready() clocked_by (saxiclk) reset_by(saxireset);
      method rresp(s_axi_rresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rresp);
      method rvalid(s_axi_rvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_rvalid);
      method s_axi_wdata wdata() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_wid wid() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_wlast wlast() clocked_by (saxiclk) reset_by(saxireset);
      method wready(s_axi_wready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_s_axi_wready);
      method s_axi_wstrb wstrb() clocked_by (saxiclk) reset_by(saxireset);
      method s_axi_wvalid wvalid() clocked_by (saxiclk) reset_by(saxireset);
   endinterface

   interface ParMaxiGp maxi;
      method araddr(m_axi_araddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_araddr);
      method arburst(m_axi_arburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arburst);
      method arcache(m_axi_arcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arcache);
      method m_axi_aresetn aresetn() clocked_by(maxiclk) reset_by(maxireset);
      method arid(m_axi_arid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arid);
      method arlen(m_axi_arlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arlen);
      method arlock(m_axi_arlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arlock);
      method arprot(m_axi_arprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arprot);
      method arqos(m_axi_arqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arqos);
      method m_axi_arready arready() clocked_by(maxiclk) reset_by(maxireset);
      method arsize(m_axi_arsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arsize);
      method arvalid(m_axi_arvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_arvalid);
      method awaddr(m_axi_awaddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awaddr);
      method awburst(m_axi_awburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awburst);
      method awcache(m_axi_awcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awcache);
      method awid(m_axi_awid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awid);
      method awlen(m_axi_awlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awlen);
      method awlock(m_axi_awlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awlock);
      method awprot(m_axi_awprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awprot);
      method awqos(m_axi_awqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awqos);
      method m_axi_awready awready() clocked_by(maxiclk) reset_by(maxireset);
      method awsize(m_axi_awsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awsize);
      method awvalid(m_axi_awvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_awvalid);
      method m_axi_bid bid() clocked_by(maxiclk) reset_by(maxireset);
      method bready(m_axi_bready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_bready);
      method m_axi_bresp bresp() clocked_by(maxiclk) reset_by(maxireset);
      method m_axi_bvalid bvalid() clocked_by(maxiclk) reset_by(maxireset);
      method m_axi_rdata rdata() clocked_by(maxiclk) reset_by(maxireset);
      method m_axi_rlast rlast() clocked_by(maxiclk) reset_by(maxireset);
      method rready(m_axi_rready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_rready);
      method m_axi_rresp rresp() clocked_by(maxiclk) reset_by(maxireset);
      method m_axi_rvalid rvalid() clocked_by(maxiclk) reset_by(maxireset);
      method wdata(m_axi_wdata) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wdata);
      method wid(m_axi_wid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wid);
      method wlast(m_axi_wlast) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wlast);
      method m_axi_wready wready() clocked_by(maxiclk) reset_by(maxireset);
      method wstrb(m_axi_wstrb) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wstrb);
      method wvalid(m_axi_wvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_m_axi_wvalid);
      method m_axi_rid rid() clocked_by(maxiclk) reset_by(maxireset);
   endinterface

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

   );

endmodule


fix clocks

fix clocks

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2012  Bluespec, Inc.  ALL RIGHTS RESERVED.
////////////////////////////////////////////////////////////////////////////////
//  Filename      : ConnectalXilinx7PCIE.bsv
//  Description   :
////////////////////////////////////////////////////////////////////////////////
package PcieEndpointX7Gen2;

import Clocks            ::*;
import Vector            ::*;
import Connectable       ::*;
import GetPut            ::*;
import Reserved          ::*;
import TieOff            ::*;
import DefaultValue      ::*;
import DReg              ::*;
import Gearbox           ::*;
import FIFO              ::*;
import FIFOF             ::*;
import SpecialFIFOs      ::*;
import ClientServer      ::*;
import Real              ::*;

import ConnectalClocks   ::*;
import ConnectalXilinxCells   ::*;
import XilinxCells       ::*;
import PCIE              ::*;
import PCIEWRAPPER2      ::*;
import Bufgctrl           ::*;
import PcieGearbox       :: *;

////////////////////////////////////////////////////////////////////////////////
/// Interfaces
////////////////////////////////////////////////////////////////////////////////

interface PcieEndpointX7#(numeric type lanes);
   interface PciewrapPci_exp#(lanes)   pcie;
   interface PciewrapUser#(lanes)      user;
   interface PciewrapCfg#(lanes)       cfg;
   interface Server#(TLPData#(16), TLPData#(16)) tlp;
   interface Clock epClock125;
   interface Reset epReset125;
   interface Clock epClock250;
   interface Reset epReset250;
   interface Clock epPortalClock;
   interface Reset epPortalReset;
   interface Clock epDerivedClock;
   interface Reset epDerivedReset;
endinterface

typedef struct {
   Bit#(22)      user;
   Bit#(1)       last;
   Bit#(16)      keep;
   Bit#(128)     data;
} AxiRx deriving (Bits, Eq);

typedef struct {
   Bit#(1)       last;
   Bit#(16)      keep;
   Bit#(128)     data;
} AxiTx deriving (Bits, Eq);

`ifdef Artix7
typedef 4 PcieLanes;
`endif
`ifdef BOARD_zc706
typedef 4 PcieLanes;
`endif
`ifdef BOARD_vc707
typedef 8 PcieLanes;
`endif
`ifdef BOARD_kc705
typedef 8 PcieLanes;
`endif
`ifdef BOARD_netfpgasume
typedef 8 PcieLanes;
`endif

(* synthesize *)
module mkPcieEndpointX7(PcieEndpointX7#(PcieLanes));

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

   PcieWrap#(PcieLanes) pcie_ep <- mkPcieWrap(defaultClock, defaultReset);

   Clock user_clk = pcie_ep.user_clk_out;
   Reset user_reset_n <- mkResetInverter(pcie_ep.user_reset_out, clocked_by user_clk);

   FIFOF#(AxiTx)             fAxiTx              <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n);
   FIFOF#(AxiRx)             fAxiRx              <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n);

   (* fire_when_enabled, no_implicit_conditions *)
   rule every1;
      pcie_ep.fc.sel(0 /*RECEIVE_BUFFER_AVAILABLE_SPACE*/);
      pcie_ep.cfg_dsn({ 32'h0000_0001, {{ 8'h1 } , 24'h000A35 }});
      pcie_ep.rx.np_ok(1);
      pcie_ep.rx.np_req(1);
      pcie_ep.tx.cfg_gnt(1);
      pcie_ep.s_axis_tx.tuser(4'b0);
      pcie_ep.m_axis_rx.tready(pack(fAxiRx.notFull));
   endrule
   rule every_cfg_err;
      pcie_ep.cfg_err.acs(0);
      pcie_ep.cfg_err.aer_headerlog(0);
      pcie_ep.cfg_err.atomic_egress_blocked(0);
      pcie_ep.cfg_err.cor(0);
      pcie_ep.cfg_err.cpl_abort(0);
      pcie_ep.cfg_err.cpl_timeout(0);
      pcie_ep.cfg_err.cpl_unexpect(0);
      pcie_ep.cfg_err.ecrc(0);
      pcie_ep.cfg_err.internal_cor(0);
      pcie_ep.cfg_err.internal_uncor(0);
      pcie_ep.cfg_err.locked(0);
      pcie_ep.cfg_err.malformed(0);
      pcie_ep.cfg_err.mc_blocked(0);
      pcie_ep.cfg_err.norecovery(0);
      pcie_ep.cfg_err.poisoned(0);
      pcie_ep.cfg_err.posted(0);
      pcie_ep.cfg_err.tlp_cpl_header(0);
      pcie_ep.cfg_err.ur(0);
   endrule
   rule every_interrupt;
      pcie_ep.cfg_interrupt.zzassert(0);
      pcie_ep.cfg_interrupt.di(0);
      pcie_ep.cfg_interrupt.stat(0);
   endrule
   rule every_mgmt;
      pcie_ep.cfg_mgmt.byte_en(0);
      pcie_ep.cfg_mgmt.di(0);
      pcie_ep.cfg_mgmt.dwaddr(0);
      pcie_ep.cfg_mgmt.rd_en(0);
      pcie_ep.cfg_mgmt.wr_en(0);
      pcie_ep.cfg_mgmt.wr_readonly(0);
   endrule
   rule every_pm;
      pcie_ep.cfg_pm.force_state(0);
      pcie_ep.cfg_pm.force_state_en(0);
      pcie_ep.cfg_pm.halt_aspm_l0s(0);
      pcie_ep.cfg_pm.halt_aspm_l1(0);
      pcie_ep.cfg_pm.send_pme_to(0);
      pcie_ep.cfg_pm.wake(0);
   endrule
   rule every_pl;
      pcie_ep.pl.directed_link_auton(0);
      pcie_ep.pl.directed_link_change(0);
      pcie_ep.pl.directed_link_speed(0);
      pcie_ep.pl.directed_link_width(0);
      pcie_ep.pl.downstream_deemph_source(0);
      pcie_ep.pl.transmit_hot_rst(0);
      pcie_ep.pl.upstream_prefer_deemph(1);
   endrule

   let txready = (pcie_ep.s_axis_tx.tready == 1 && fAxiTx.notEmpty);

   (* fire_when_enabled *)
   rule drive_axi_tx if (txready);
      let info = unpack(0);
      if (fAxiTx.notEmpty) begin
	 info <- toGet(fAxiTx).get();
      end
      pcie_ep.s_axis_tx.tlast(info.last);
      pcie_ep.s_axis_tx.tdata(info.data);
      pcie_ep.s_axis_tx.tkeep(info.keep);
   endrule
   (* fire_when_enabled, no_implicit_conditions *)
   rule drive_axi_txvalid if (fAxiTx.notEmpty);
      pcie_ep.s_axis_tx.tvalid(1);
   endrule
   (* fire_when_enabled, no_implicit_conditions *)
   rule drive_axi_tx2 if (!fAxiTx.notEmpty);
      pcie_ep.s_axis_tx.tvalid(0);
      pcie_ep.s_axis_tx.tlast(0);
      pcie_ep.s_axis_tx.tdata(0);
      pcie_ep.s_axis_tx.tkeep(0);
   endrule

   (* fire_when_enabled *)
   rule sink_axi_rx if (pcie_ep.m_axis_rx.tvalid == 1);
      fAxiRx.enq(AxiRx {user: pcie_ep.m_axis_rx.tuser,
                        last: pcie_ep.m_axis_rx.tlast,
                        keep: pcie_ep.m_axis_rx.tkeep,
                        data: pcie_ep.m_axis_rx.tdata });
   endrule

   Reset user_reset <- mkAsyncReset(4, user_reset_n, user_clk);

   ClockGenerator7Params     clkgenParams = defaultValue;
   clkgenParams.clkin1_period    = 4.000; //  250MHz
   clkgenParams.clkin_buffer     = False;
   clkgenParams.clkfbout_mult_f  = 4.000; // 1000MHz
   clkgenParams.clkout0_divide_f = 4.000; //  250MHz
   clkgenParams.clkout1_divide     = round(mainClockPeriod);
   clkgenParams.clkout1_duty_cycle = 0.5;
   clkgenParams.clkout1_phase      = 0.0000;
   clkgenParams.clkout2_divide     = round(derivedClockPeriod);
   clkgenParams.clkout2_duty_cycle = 0.5;
   clkgenParams.clkout2_phase      = 0.0000;
   ClockGenerator7           clkgen <- mkClockGenerator7(clkgenParams, clocked_by user_clk, reset_by user_reset_n);
   Clock portalClock = clkgen.clkout1;
   Reset portalReset <- mkAsyncReset(4, user_reset_n, portalClock);
   Clock derivedClock = clkgen.clkout2;
   Reset derivedReset <- mkAsyncReset(4, user_reset_n, derivedClock);

   Server#(TLPData#(16), TLPData#(16)) tlp16 = (interface Server;
						interface Put request;
						   method Action put(TLPData#(16) data);
						      fAxiTx.enq(AxiTx {last: pack(data.eof),
									keep: dwordSwap128BE(data.be), data: dwordSwap128(data.data) });
						   endmethod
						endinterface
						interface Get response;
						   method ActionValue#(TLPData#(16)) get();
						      let info <- toGet(fAxiRx).get;
						      TLPData#(16) retval = defaultValue;
						      retval.sof  = (info.user[14] == 1);
						      retval.eof  = info.last != 0;
						      retval.hit  = info.user[8:2];
						      retval.be= dwordSwap128BE(info.keep);
						      retval.data = dwordSwap128(info.data);
						      return retval;
						   endmethod
						endinterface
					     endinterface);

   interface Clock epClock250 = user_clk;
   interface Reset epReset250 = user_reset_n;
   interface Clock epClock125 = user_clk;
   interface Reset epReset125 = user_reset_n;
   interface tlp = tlp16;
   interface pcie    = pcie_ep.pci_exp;
   interface PciewrapUser user = pcie_ep.user;
   interface PciewrapCfg cfg = pcie_ep.cfg;
   interface Clock epPortalClock = portalClock;
   interface Reset epPortalReset = portalReset;
   interface Clock epDerivedClock = derivedClock;
   interface Reset epDerivedReset = derivedReset;
endmodule: mkPcieEndpointX7

endpackage: PcieEndpointX7Gen2

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2012  Bluespec, Inc.  ALL RIGHTS RESERVED.
////////////////////////////////////////////////////////////////////////////////
//  Filename      : ConnectalXilinx7PCIE.bsv
//  Description   :
////////////////////////////////////////////////////////////////////////////////
package PcieEndpointX7Gen2;

import Clocks            ::*;
import Vector            ::*;
import Connectable       ::*;
import GetPut            ::*;
import Reserved          ::*;
import TieOff            ::*;
import DefaultValue      ::*;
import DReg              ::*;
import Gearbox           ::*;
import FIFO              ::*;
import FIFOF             ::*;
import SpecialFIFOs      ::*;
import ClientServer      ::*;
import Real              ::*;

import ConnectalClocks   ::*;
import ConnectalXilinxCells   ::*;
import XilinxCells       ::*;
import PCIE              ::*;
import PCIEWRAPPER2      ::*;
import Bufgctrl           ::*;
import PcieGearbox       :: *;

////////////////////////////////////////////////////////////////////////////////
/// Interfaces
////////////////////////////////////////////////////////////////////////////////

interface PcieEndpointX7#(numeric type lanes);
   interface PciewrapPci_exp#(lanes)   pcie;
   interface PciewrapUser#(lanes)      user;
   interface PciewrapCfg#(lanes)       cfg;
   interface Server#(TLPData#(16), TLPData#(16)) tlp;
   interface Clock portalClock;
   interface Reset portalReset;
   interface Clock epDerivedClock;
   interface Reset epDerivedReset;
endinterface

typedef struct {
   Bit#(22)      user;
   Bit#(1)       last;
   Bit#(16)      keep;
   Bit#(128)     data;
} AxiRx deriving (Bits, Eq);

typedef struct {
   Bit#(1)       last;
   Bit#(16)      keep;
   Bit#(128)     data;
} AxiTx deriving (Bits, Eq);

`ifdef Artix7
typedef 4 PcieLanes;
`endif
`ifdef BOARD_zc706
typedef 4 PcieLanes;
`endif
`ifdef BOARD_vc707
typedef 8 PcieLanes;
`endif
`ifdef BOARD_kc705
typedef 8 PcieLanes;
`endif
`ifdef BOARD_netfpgasume
typedef 8 PcieLanes;
`endif

(* synthesize *)
module mkPcieEndpointX7(PcieEndpointX7#(PcieLanes));

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

   PcieWrap#(PcieLanes) pcie_ep <- mkPcieWrap(defaultClock, defaultReset);

   Clock user_clk = pcie_ep.user_clk_out;
   Reset user_reset_n <- mkResetInverter(pcie_ep.user_reset_out, clocked_by user_clk);

   FIFOF#(AxiTx)             fAxiTx              <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n);
   FIFOF#(AxiRx)             fAxiRx              <- mkFIFOF(clocked_by user_clk, reset_by user_reset_n);

   (* fire_when_enabled, no_implicit_conditions *)
   rule every1;
      pcie_ep.fc.sel(0 /*RECEIVE_BUFFER_AVAILABLE_SPACE*/);
      pcie_ep.cfg_dsn({ 32'h0000_0001, {{ 8'h1 } , 24'h000A35 }});
      pcie_ep.rx.np_ok(1);
      pcie_ep.rx.np_req(1);
      pcie_ep.tx.cfg_gnt(1);
      pcie_ep.s_axis_tx.tuser(4'b0);
      pcie_ep.m_axis_rx.tready(pack(fAxiRx.notFull));
   endrule
   rule every_cfg_err;
      pcie_ep.cfg_err.acs(0);
      pcie_ep.cfg_err.aer_headerlog(0);
      pcie_ep.cfg_err.atomic_egress_blocked(0);
      pcie_ep.cfg_err.cor(0);
      pcie_ep.cfg_err.cpl_abort(0);
      pcie_ep.cfg_err.cpl_timeout(0);
      pcie_ep.cfg_err.cpl_unexpect(0);
      pcie_ep.cfg_err.ecrc(0);
      pcie_ep.cfg_err.internal_cor(0);
      pcie_ep.cfg_err.internal_uncor(0);
      pcie_ep.cfg_err.locked(0);
      pcie_ep.cfg_err.malformed(0);
      pcie_ep.cfg_err.mc_blocked(0);
      pcie_ep.cfg_err.norecovery(0);
      pcie_ep.cfg_err.poisoned(0);
      pcie_ep.cfg_err.posted(0);
      pcie_ep.cfg_err.tlp_cpl_header(0);
      pcie_ep.cfg_err.ur(0);
   endrule
   rule every_interrupt;
      pcie_ep.cfg_interrupt.zzassert(0);
      pcie_ep.cfg_interrupt.di(0);
      pcie_ep.cfg_interrupt.stat(0);
   endrule
   rule every_mgmt;
      pcie_ep.cfg_mgmt.byte_en(0);
      pcie_ep.cfg_mgmt.di(0);
      pcie_ep.cfg_mgmt.dwaddr(0);
      pcie_ep.cfg_mgmt.rd_en(0);
      pcie_ep.cfg_mgmt.wr_en(0);
      pcie_ep.cfg_mgmt.wr_readonly(0);
   endrule
   rule every_pm;
      pcie_ep.cfg_pm.force_state(0);
      pcie_ep.cfg_pm.force_state_en(0);
      pcie_ep.cfg_pm.halt_aspm_l0s(0);
      pcie_ep.cfg_pm.halt_aspm_l1(0);
      pcie_ep.cfg_pm.send_pme_to(0);
      pcie_ep.cfg_pm.wake(0);
   endrule
   rule every_pl;
      pcie_ep.pl.directed_link_auton(0);
      pcie_ep.pl.directed_link_change(0);
      pcie_ep.pl.directed_link_speed(0);
      pcie_ep.pl.directed_link_width(0);
      pcie_ep.pl.downstream_deemph_source(0);
      pcie_ep.pl.transmit_hot_rst(0);
      pcie_ep.pl.upstream_prefer_deemph(1);
   endrule

   let txready = (pcie_ep.s_axis_tx.tready == 1 && fAxiTx.notEmpty);

   (* fire_when_enabled *)
   rule drive_axi_tx if (txready);
      let info = unpack(0);
      if (fAxiTx.notEmpty) begin
	 info <- toGet(fAxiTx).get();
      end
      pcie_ep.s_axis_tx.tlast(info.last);
      pcie_ep.s_axis_tx.tdata(info.data);
      pcie_ep.s_axis_tx.tkeep(info.keep);
   endrule
   (* fire_when_enabled, no_implicit_conditions *)
   rule drive_axi_txvalid if (fAxiTx.notEmpty);
      pcie_ep.s_axis_tx.tvalid(1);
   endrule
   (* fire_when_enabled, no_implicit_conditions *)
   rule drive_axi_tx2 if (!fAxiTx.notEmpty);
      pcie_ep.s_axis_tx.tvalid(0);
      pcie_ep.s_axis_tx.tlast(0);
      pcie_ep.s_axis_tx.tdata(0);
      pcie_ep.s_axis_tx.tkeep(0);
   endrule

   (* fire_when_enabled *)
   rule sink_axi_rx if (pcie_ep.m_axis_rx.tvalid == 1);
      fAxiRx.enq(AxiRx {user: pcie_ep.m_axis_rx.tuser,
                        last: pcie_ep.m_axis_rx.tlast,
                        keep: pcie_ep.m_axis_rx.tkeep,
                        data: pcie_ep.m_axis_rx.tdata });
   endrule

   Reset user_reset <- mkAsyncReset(4, user_reset_n, user_clk);

   ClockGenerator7Params     clkgenParams = defaultValue;
   clkgenParams.clkin1_period    = 4.000; //  250MHz
   clkgenParams.clkin_buffer     = False;
   clkgenParams.clkfbout_mult_f  = 4.000; // 1000MHz
   clkgenParams.clkout0_divide_f = 4.000; //  250MHz
   clkgenParams.clkout1_divide     = round(derivedClockPeriod);
   clkgenParams.clkout1_duty_cycle = 0.5;
   clkgenParams.clkout1_phase      = 0.0000;
   ClockGenerator7           clkgen <- mkClockGenerator7(clkgenParams, clocked_by user_clk, reset_by user_reset_n);
   Clock derivedClock = clkgen.clkout1;
   Reset derivedReset <- mkAsyncReset(4, user_reset_n, derivedClock);

   Server#(TLPData#(16), TLPData#(16)) tlp16 = (interface Server;
						interface Put request;
						   method Action put(TLPData#(16) data);
						      fAxiTx.enq(AxiTx {last: pack(data.eof),
									keep: dwordSwap128BE(data.be), data: dwordSwap128(data.data) });
						   endmethod
						endinterface
						interface Get response;
						   method ActionValue#(TLPData#(16)) get();
						      let info <- toGet(fAxiRx).get;
						      TLPData#(16) retval = defaultValue;
						      retval.sof  = (info.user[14] == 1);
						      retval.eof  = info.last != 0;
						      retval.hit  = info.user[8:2];
						      retval.be= dwordSwap128BE(info.keep);
						      retval.data = dwordSwap128(info.data);
						      return retval;
						   endmethod
						endinterface
					     endinterface);

   interface Clock portalClock = user_clk;
   interface Reset portalReset = user_reset_n;
   interface tlp = tlp16;
   interface pcie    = pcie_ep.pci_exp;
   interface PciewrapUser user = pcie_ep.user;
   interface PciewrapCfg cfg = pcie_ep.cfg;
   interface Clock epDerivedClock = derivedClock;
   interface Reset epDerivedReset = derivedReset;
endmodule: mkPcieEndpointX7

endpackage: PcieEndpointX7Gen2


reduce gearbox fifo size

reduce gearbox fifo size

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

import BuildVector::*;
import DefaultValue::*;
import GetPut::*;
import FIFO::*;
import FIFOF::*;
import BRAMFIFO::*;
import Vector::*;
import Stream::*;
import Gearbox::*;
import SynthBuilder::*;
import PrintTrace::*;

`include "SynthBuilder.defines"

interface StreamGearbox#(numeric type n, numeric type m);
   interface Put#(ByteStream#(n)) datain;
   interface Get#(ByteStream#(m)) dataout;
   method Bit#(64) getEopCount;
   method Bit#(64) getSopCount;
   method Bit#(64) getIdleCount;
   method Bit#(64) getDataCount;
endinterface

typeclass GetGearbox#(numeric type n, numeric type m);
   function Put#(ByteStream#(n)) getDataIn(StreamGearbox#(n, m) gb);
   function Get#(ByteStream#(m)) getDataOut(StreamGearbox#(n, m) gb);
endtypeclass

instance GetGearbox#(n, m);
   function Put#(ByteStream#(n)) getDataIn(StreamGearbox#(n, m) gb);
      return gb.datain;
   endfunction
   function Get#(ByteStream#(m)) getDataOut(StreamGearbox#(n, m) gb);
      return gb.dataout;
   endfunction
endinstance

typeclass MkStreamGearboxUp#(numeric type n, numeric type m);
   module mkStreamGearboxUp(StreamGearbox#(n, m));
endtypeclass

// Gearbox Box 1-to-2
instance MkStreamGearboxUp#(n, m)
   provisos(Mul#(n, 2, m)
           ,Add#(a__, TLog#(TAdd#(1, n)), 64)
           ,Add#(1, b__, TLog#(TAdd#(1, n))));
   module mkStreamGearboxUp(StreamGearbox#(n, m));
      let verbose = False;
      FIFOF#(ByteStream#(n)) in_ff <- mkFIFOF;
      FIFOF#(ByteStream#(m)) out_ff <- mkFIFOF;
      Reg#(Bool) inProgress <- mkReg(False);
      Reg#(Bool) oddBeat    <- mkReg(True);
      Reg#(ByteStream#(n)) v_prev <- mkReg(defaultValue);

      Reg#(Bit#(64)) idle_cycles <- mkReg(0);
      Reg#(Bit#(64)) sopCount <- mkReg(0);
      Reg#(Bit#(64)) eopCount <- mkReg(0);
      Reg#(Bit#(64)) data_bytes <- mkReg(0);

      function ByteStream#(m) combine(Vector#(2, ByteStream#(n)) v);
         ByteStream#(m) data = defaultValue;
         data.data = {v[1].data, v[0].data};
         data.mask = {v[1].mask, v[0].mask};
         data.user = v[0].user;
         data.sop = v[0].sop;
         data.eop = v[0].eop || v[1].eop;
         return data;
      endfunction
      rule startOfPacket if (!inProgress);
         let v = in_ff.first;
         inProgress <= v.sop;
         if (!v.sop)
            in_ff.deq;
         else
            sopCount <= sopCount + 1;
         if (verbose) $display("gearbox start");
      endrule
      rule readPacketOdd if (inProgress && oddBeat);
         let v <- toGet(in_ff).get;
         if (verbose) $display("gearbox read odd beat %h", v.data);
         let bytes = zeroExtend(pack(countOnes(v.mask)));
         data_bytes <= data_bytes + bytes;
         if (v.eop) begin
            ByteStream#(n) vo = defaultValue;
            out_ff.enq(combine(vec(v, vo)));
            if (verbose) $display("gearbox odd eop %h %h", v.data, v.mask);
            inProgress <= False;
            eopCount <= eopCount + 1;
         end
         else begin
            oddBeat <= !oddBeat;
         end
         v_prev <= v;
      endrule

      rule readPacketEven if (inProgress && !oddBeat);
         let v <- toGet(in_ff).get;
         let bytes = zeroExtend(pack(countOnes(v.mask)));
         data_bytes <= data_bytes + bytes;
         out_ff.enq(combine(vec(v_prev, v)));
         if (verbose) $display("gearbox read even beat %h", v.data);
         if (v.eop) begin
            inProgress <= False;
            if (verbose) $display("gearbox even eop %h %h %h %h", v.data, v.mask, v_prev.data, v_prev.mask);
            eopCount <= eopCount + 1;
         end
         oddBeat <= !oddBeat;
      endrule

      rule count_idle_cycles (!inProgress);
         idle_cycles <= idle_cycles + 1;
      endrule

      interface datain = toPut(in_ff);
      interface dataout = toGet(out_ff);
      method Bit#(64) getEopCount;
         return eopCount;
      endmethod
      method Bit#(64) getSopCount;
         return sopCount;
      endmethod
      method Bit#(64) getIdleCount;
         return idle_cycles;
      endmethod
      method Bit#(64) getDataCount;
         return data_bytes;
      endmethod
   endmodule
endinstance

typeclass MkStreamGearboxDn#(numeric type n, numeric type m);
   module mkStreamGearboxDn(StreamGearbox#(n, m));
endtypeclass

// Gearbox 2-to-1
instance MkStreamGearboxDn#(n, m) provisos(Mul#(m, 2, n));
   module mkStreamGearboxDn(StreamGearbox#(n, m));
      let clock <- exposeCurrentClock();
      let reset <- exposeCurrentReset();

      FIFOF#(ByteStream#(n)) in_ff <- mkFIFOF;
      FIFOF#(ByteStream#(m)) out_ff <- mkFIFOF;
      Gearbox#(2, 1, ByteStream#(m)) fifoTxData <- mkNto1Gearbox(clock, reset, clock, reset);

      function Vector#(2, ByteStream#(m)) split(ByteStream#(n) in);
         Vector#(2, ByteStream#(m)) v = defaultValue;
         Vector#(2, Bit#(TMul#(m, 8))) data = unpack(in.data);
         Vector#(2, Bit#(m)) mask = unpack(in.mask);
         v[0].sop = in.sop;
         v[0].data = data[0];
         v[0].eop = (mask[1] == 0) ? in.eop : False;
         v[0].mask = mask[0];
         v[0].user = in.user;
         v[1].sop = False;
         v[1].data = data[1];
         v[1].eop = in.eop;
         v[1].mask = mask[1];
         v[1].user = in.user;
         return v;
      endfunction

      rule process_incoming_packet;
         let v <- toGet(in_ff).get;
         fifoTxData.enq(split(v));
      endrule

      rule process_outgoing_packet;
         let data = fifoTxData.first; fifoTxData.deq;
         let temp = head(data);
         let bytes = zeroExtend(pack(countOnes(temp.mask)));
         if (temp.mask != 0) begin
            out_ff.enq(temp);
         end
      endrule

      interface datain = toPut(in_ff);
      interface dataout = toGet(out_ff);
   endmodule
endinstance

`SynthBuildModule(mkStreamGearboxUp, StreamGearbox#(16, 32), mkStreamGearboxUp_16_32)
`SynthBuildModule(mkStreamGearboxUp, StreamGearbox#(32, 64), mkStreamGearboxUp_32_64)
`SynthBuildModule(mkStreamGearboxDn, StreamGearbox#(32, 16), mkStreamGearboxDn_32_16)
`SynthBuildModule(mkStreamGearboxDn, StreamGearbox#(64, 32), mkStreamGearboxDn_64_32)

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

import BuildVector::*;
import DefaultValue::*;
import GetPut::*;
import FIFO::*;
import FIFOF::*;
import Vector::*;
import Stream::*;
import Gearbox::*;
import SynthBuilder::*;
import PrintTrace::*;

`include "SynthBuilder.defines"

interface StreamGearbox#(numeric type n, numeric type m);
   interface Put#(ByteStream#(n)) datain;
   interface Get#(ByteStream#(m)) dataout;
   method Bit#(64) getEopCount;
   method Bit#(64) getSopCount;
   method Bit#(64) getIdleCount;
   method Bit#(64) getDataCount;
endinterface

typeclass GetGearbox#(numeric type n, numeric type m);
   function Put#(ByteStream#(n)) getDataIn(StreamGearbox#(n, m) gb);
   function Get#(ByteStream#(m)) getDataOut(StreamGearbox#(n, m) gb);
endtypeclass

instance GetGearbox#(n, m);
   function Put#(ByteStream#(n)) getDataIn(StreamGearbox#(n, m) gb);
      return gb.datain;
   endfunction
   function Get#(ByteStream#(m)) getDataOut(StreamGearbox#(n, m) gb);
      return gb.dataout;
   endfunction
endinstance

typeclass MkStreamGearboxUp#(numeric type n, numeric type m);
   module mkStreamGearboxUp(StreamGearbox#(n, m));
endtypeclass

// Gearbox Box 1-to-2
instance MkStreamGearboxUp#(n, m)
   provisos(Mul#(n, 2, m)
           ,Add#(a__, TLog#(TAdd#(1, n)), 64)
           ,Add#(1, b__, TLog#(TAdd#(1, n))));
   module mkStreamGearboxUp(StreamGearbox#(n, m));
      let verbose = False;
      FIFOF#(ByteStream#(n)) in_ff <- mkSizedFIFOF(2);
      FIFOF#(ByteStream#(m)) out_ff <- mkSizedFIFOF(2);
      Reg#(Bool) inProgress <- mkReg(False);
      Reg#(Bool) oddBeat    <- mkReg(True);
      Reg#(ByteStream#(n)) v_prev <- mkReg(defaultValue);

      Reg#(Bit#(64)) idle_cycles <- mkReg(0);
      Reg#(Bit#(64)) sopCount <- mkReg(0);
      Reg#(Bit#(64)) eopCount <- mkReg(0);
      Reg#(Bit#(64)) data_bytes <- mkReg(0);

      function ByteStream#(m) combine(Vector#(2, ByteStream#(n)) v);
         ByteStream#(m) data = defaultValue;
         data.data = {v[1].data, v[0].data};
         data.mask = {v[1].mask, v[0].mask};
         data.user = v[0].user;
         data.sop = v[0].sop;
         data.eop = v[0].eop || v[1].eop;
         return data;
      endfunction
      rule startOfPacket if (!inProgress);
         let v = in_ff.first;
         inProgress <= v.sop;
         if (!v.sop)
            in_ff.deq;
         else
            sopCount <= sopCount + 1;
         if (verbose) $display("gearbox start");
      endrule
      rule readPacketOdd if (inProgress && oddBeat);
         let v <- toGet(in_ff).get;
         if (verbose) $display("gearbox read odd beat %h", v.data);
         let bytes = zeroExtend(pack(countOnes(v.mask)));
         data_bytes <= data_bytes + bytes;
         if (v.eop) begin
            ByteStream#(n) vo = defaultValue;
            out_ff.enq(combine(vec(v, vo)));
            if (verbose) $display("gearbox odd eop %h %h", v.data, v.mask);
            inProgress <= False;
            eopCount <= eopCount + 1;
         end
         else begin
            oddBeat <= !oddBeat;
         end
         v_prev <= v;
      endrule

      rule readPacketEven if (inProgress && !oddBeat);
         let v <- toGet(in_ff).get;
         let bytes = zeroExtend(pack(countOnes(v.mask)));
         data_bytes <= data_bytes + bytes;
         out_ff.enq(combine(vec(v_prev, v)));
         if (verbose) $display("gearbox read even beat %h", v.data);
         if (v.eop) begin
            inProgress <= False;
            if (verbose) $display("gearbox even eop %h %h %h %h", v.data, v.mask, v_prev.data, v_prev.mask);
            eopCount <= eopCount + 1;
         end
         oddBeat <= !oddBeat;
      endrule

      rule count_idle_cycles (!inProgress);
         idle_cycles <= idle_cycles + 1;
      endrule

      interface datain = toPut(in_ff);
      interface dataout = toGet(out_ff);
      method Bit#(64) getEopCount;
         return eopCount;
      endmethod
      method Bit#(64) getSopCount;
         return sopCount;
      endmethod
      method Bit#(64) getIdleCount;
         return idle_cycles;
      endmethod
      method Bit#(64) getDataCount;
         return data_bytes;
      endmethod
   endmodule
endinstance

typeclass MkStreamGearboxDn#(numeric type n, numeric type m);
   module mkStreamGearboxDn(StreamGearbox#(n, m));
endtypeclass

// Gearbox 2-to-1
instance MkStreamGearboxDn#(n, m) provisos(Mul#(m, 2, n));
   module mkStreamGearboxDn(StreamGearbox#(n, m));
      let clock <- exposeCurrentClock();
      let reset <- exposeCurrentReset();

      FIFO#(ByteStream#(n)) in_ff <- mkFIFO;
      FIFO#(ByteStream#(m)) out_ff <- mkFIFO;
      Gearbox#(2, 1, ByteStream#(m)) fifoTxData <- mkNto1Gearbox(clock, reset, clock, reset);

      function Vector#(2, ByteStream#(m)) split(ByteStream#(n) in);
         Vector#(2, ByteStream#(m)) v = defaultValue;
         Vector#(2, Bit#(TMul#(m, 8))) data = unpack(in.data);
         Vector#(2, Bit#(m)) mask = unpack(in.mask);
         v[0].sop = in.sop;
         v[0].data = data[0];
         v[0].eop = (mask[1] == 0) ? in.eop : False;
         v[0].mask = mask[0];
         v[0].user = in.user;
         v[1].sop = False;
         v[1].data = data[1];
         v[1].eop = in.eop;
         v[1].mask = mask[1];
         v[1].user = in.user;
         return v;
      endfunction

      rule process_incoming_packet;
         let v <- toGet(in_ff).get;
         fifoTxData.enq(split(v));
      endrule

      rule process_outgoing_packet;
         let data = fifoTxData.first; fifoTxData.deq;
         let temp = head(data);
         let bytes = zeroExtend(pack(countOnes(temp.mask)));
         if (temp.mask != 0) begin
            out_ff.enq(temp);
         end
      endrule

      interface datain = toPut(in_ff);
      interface dataout = toGet(out_ff);
   endmodule
endinstance

`SynthBuildModule(mkStreamGearboxUp, StreamGearbox#(16, 32), mkStreamGearboxUp_16_32)
`SynthBuildModule(mkStreamGearboxUp, StreamGearbox#(32, 64), mkStreamGearboxUp_32_64)
`SynthBuildModule(mkStreamGearboxDn, StreamGearbox#(32, 16), mkStreamGearboxDn_32_16)
`SynthBuildModule(mkStreamGearboxDn, StreamGearbox#(64, 32), mkStreamGearboxDn_64_32)


dangling bluescope ref

dangling bluescope ref

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

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

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

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

import Vector::*;
import FIFOF::*;
import GetPutF::*;

import PortalMemory::*;
import Dma::*;

interface PerfRequest;
   method Action startCopy(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) numWords);
   method Action readWord();
   method Action getStateDbg();
endinterface

interface PerfIndication;
   method Action started(Bit#(32) numWords);
   method Action readWordResult(Bit#(32) v);
   method Action done(Bit#(32) dataMismatch);
   method Action rData(Bit#(64) v);
   method Action readReq(Bit#(32) v);
   method Action writeReq(Bit#(32) v);
   method Action writeAck(Bit#(32) v);
   method Action reportStateDbg(Bit#(32) srcGen, Bit#(32) streamRdCnt, Bit#(32) streamWrCnt, Bit#(32) writeInProg, Bit#(32) dataMismatch);
endinterface

module mkPerfRequest#(PerfIndication indication,
			DmaReadServer#(busWidth) dma_stream_read_server,
			DmaWriteServer#(busWidth) dma_stream_write_server,
			DmaReadServer#(busWidth) dma_word_read_server)
   (PerfRequest)
   provisos (Div#(busWidth,8,busWidthBytes),
	     Add#(a__,32,busWidth));

   let busWidthBytes = valueOf(busWidthBytes);
   let busWidthWords = busWidthBytes/4;

   Reg#(Bit#(32))      srcGen <- mkReg(0);
   Reg#(Bit#(32)) streamRdCnt <- mkReg(0);
   Reg#(Bit#(32)) streamWrCnt <- mkReg(0);
   Reg#(Bit#(32)) streamAckCnt <- mkReg(0);
   Reg#(Bit#(DmaOffsetSize)) streamRdOff <- mkReg(0);
   Reg#(Bit#(DmaOffsetSize)) streamWrOff <- mkReg(0);
   Reg#(DmaPointer)    streamRdPointer <- mkReg(0);
   Reg#(DmaPointer)    streamWrPointer <- mkReg(0);
   Reg#(Bool)               writeInProg <- mkReg(False);
   Reg#(Bool)              dataMismatch <- mkReg(False);

   Reg#(Bit#(8)) burstLen <- mkReg(8);
   Reg#(Bit#(DmaOffsetSize)) deltaOffset <- mkReg(8*fromInteger(busWidthBytes));

   rule readReq(streamRdCnt > 0);
      streamRdCnt <= streamRdCnt - extend(burstLen);
      streamRdOff <= streamRdOff + deltaOffset;
      //$display("readReq.put pointer=%h address=%h, burstlen=%h", streamRdPointer, streamRdOff, burstLen);
      dma_stream_read_server.readReq.put(DmaRequest {pointer: streamRdPointer, offset: streamRdOff, burstLen: extend(burstLen), tag: truncate(streamRdOff>>5)});
      //indication.readReq(streamRdCnt);
   endrule

   rule writeReq(streamWrCnt > 0 && !writeInProg);
      writeInProg <= True;
      streamWrCnt <= streamWrCnt-extend(burstLen);
      streamWrOff <= streamWrOff + deltaOffset;
      //$display("writeReq.put pointer=%h address=%h", streamWrPointer, streamWrOff);
      dma_stream_write_server.writeReq.put(DmaRequest {pointer: streamWrPointer, offset: streamWrOff, burstLen: extend(burstLen), tag: truncate(streamWrOff>>5)});
      //indication.writeReq(streamWrCnt);
   endrule

   rule writeAck(writeInProg);
      writeInProg <= False;
      let tag <- dma_stream_write_server.writeDone.get();
      //$display("writeAck: tag=%d", tag);
      streamAckCnt <= streamAckCnt-extend(burstLen);
      //indication.writeAck(streamAckCnt);
      if(streamAckCnt==extend(burstLen))
   	 indication.done(dataMismatch ? 32'd1 : 32'd0);
   endrule

   rule loopback;
      let tagdata <- dma_stream_read_server.readData.get();
      let v = tagdata.data;
      Bool mismatch = False;
      for (Integer i = 0; i < busWidthWords; i = i+1)
	 mismatch = mismatch || (v[31+i*32:i*32] != (srcGen + fromInteger(i)));
      dataMismatch <= dataMismatch || mismatch;
      dma_stream_write_server.writeData.put(tagdata);
      srcGen <= srcGen+fromInteger(busWidthWords);
      //$display("loopback %h", tagdata.data);
      // indication.rData(v);
   endrule

   rule readWordResp;
      let tagdata <- dma_word_read_server.readData.get;
      indication.readWordResult(truncate(tagdata.data));
   endrule

   method Action startCopy(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) numWords) if (streamRdCnt == 0 && streamWrCnt == 0);
      //$display("startCopy wrPointer=%h rdPointer=%h numWords=%d", wrPointer, rdPointer, numWords);
      streamRdOff <= 0;
      streamWrOff <= 0;

      streamWrPointer <= wrPointer;
      streamRdPointer <= rdPointer;
      streamRdCnt <= numWords>>1;
      streamWrCnt <= numWords>>1;
      streamAckCnt <= numWords>>1;
      indication.started(numWords);
   endmethod

   method Action readWord();
      dma_word_read_server.readReq.put(DmaRequest {pointer: streamWrPointer, offset: 0, burstLen: 1, tag: 1});
   endmethod

   method Action getStateDbg();
      indication.reportStateDbg(srcGen, streamRdCnt, streamWrCnt, writeInProg ? 32'd1 : 32'd0, dataMismatch  ? 32'd1 : 32'd0);
   endmethod

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 Vector::*;
import FIFOF::*;
import GetPutF::*;

import PortalMemory::*;
import Dma::*;

interface PerfRequest;
   method Action startCopy(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) numWords);
   method Action readWord();
   method Action getStateDbg();
endinterface

interface PerfIndication;
   method Action started(Bit#(32) numWords);
   method Action readWordResult(Bit#(32) v);
   method Action done(Bit#(32) dataMismatch);
   method Action rData(Bit#(64) v);
   method Action readReq(Bit#(32) v);
   method Action writeReq(Bit#(32) v);
   method Action writeAck(Bit#(32) v);
   method Action reportStateDbg(Bit#(32) srcGen, Bit#(32) streamRdCnt, Bit#(32) streamWrCnt, Bit#(32) writeInProg, Bit#(32) dataMismatch);
endinterface

module mkPerfRequest#(PerfIndication indication,
			DmaReadServer#(busWidth) dma_stream_read_server,
			DmaWriteServer#(busWidth) dma_stream_write_server,
			DmaReadServer#(busWidth) dma_word_read_server)
   (PerfRequest)
   provisos (Div#(busWidth,8,busWidthBytes),
	     Add#(a__,32,busWidth));

   let busWidthBytes = valueOf(busWidthBytes);
   let busWidthWords = busWidthBytes/4;

   Reg#(Bit#(32))      srcGen <- mkReg(0);
   Reg#(Bit#(32)) streamRdCnt <- mkReg(0);
   Reg#(Bit#(32)) streamWrCnt <- mkReg(0);
   Reg#(Bit#(32)) streamAckCnt <- mkReg(0);
   Reg#(Bit#(DmaOffsetSize)) streamRdOff <- mkReg(0);
   Reg#(Bit#(DmaOffsetSize)) streamWrOff <- mkReg(0);
   Reg#(DmaPointer)    streamRdPointer <- mkReg(0);
   Reg#(DmaPointer)    streamWrPointer <- mkReg(0);
   Reg#(Bool)               writeInProg <- mkReg(False);
   Reg#(Bool)              dataMismatch <- mkReg(False);

   Reg#(Bit#(8)) burstLen <- mkReg(8);
   Reg#(Bit#(DmaOffsetSize)) deltaOffset <- mkReg(8*fromInteger(busWidthBytes));

   rule readReq(streamRdCnt > 0);
      streamRdCnt <= streamRdCnt - extend(burstLen);
      streamRdOff <= streamRdOff + deltaOffset;
      //$display("readReq.put pointer=%h address=%h, burstlen=%h", streamRdPointer, streamRdOff, burstLen);
      dma_stream_read_server.readReq.put(DmaRequest {pointer: streamRdPointer, offset: streamRdOff, burstLen: extend(burstLen), tag: truncate(streamRdOff>>5)});
      //indication.readReq(streamRdCnt);
   endrule

   rule writeReq(streamWrCnt > 0 && !writeInProg);
      writeInProg <= True;
      streamWrCnt <= streamWrCnt-extend(burstLen);
      streamWrOff <= streamWrOff + deltaOffset;
      //$display("writeReq.put pointer=%h address=%h", streamWrPointer, streamWrOff);
      dma_stream_write_server.writeReq.put(DmaRequest {pointer: streamWrPointer, offset: streamWrOff, burstLen: extend(burstLen), tag: truncate(streamWrOff>>5)});
      //indication.writeReq(streamWrCnt);
   endrule

   rule writeAck(writeInProg);
      writeInProg <= False;
      let tag <- dma_stream_write_server.writeDone.get();
      //$display("writeAck: tag=%d", tag);
      streamAckCnt <= streamAckCnt-extend(burstLen);
      //indication.writeAck(streamAckCnt);
      if(streamAckCnt==extend(burstLen))
   	 indication.done(dataMismatch ? 32'd1 : 32'd0);
   endrule

   rule loopback;
      let tagdata <- dma_stream_read_server.readData.get();
      let v = tagdata.data;
      Bool mismatch = False;
      for (Integer i = 0; i < busWidthWords; i = i+1)
	 mismatch = mismatch || (v[31+i*32:i*32] != (srcGen + fromInteger(i)));
      dataMismatch <= dataMismatch || mismatch;
      dma_stream_write_server.writeData.put(tagdata);
      bs.dataIn(v,v);
      srcGen <= srcGen+fromInteger(busWidthWords);
      //$display("loopback %h", tagdata.data);
      // indication.rData(v);
   endrule

   rule readWordResp;
      let tagdata <- dma_word_read_server.readData.get;
      indication.readWordResult(truncate(tagdata.data));
   endrule

   method Action startCopy(Bit#(32) wrPointer, Bit#(32) rdPointer, Bit#(32) numWords) if (streamRdCnt == 0 && streamWrCnt == 0);
      //$display("startCopy wrPointer=%h rdPointer=%h numWords=%d", wrPointer, rdPointer, numWords);
      streamRdOff <= 0;
      streamWrOff <= 0;

      streamWrPointer <= wrPointer;
      streamRdPointer <= rdPointer;
      streamRdCnt <= numWords>>1;
      streamWrCnt <= numWords>>1;
      streamAckCnt <= numWords>>1;
      indication.started(numWords);
   endmethod

   method Action readWord();
      dma_word_read_server.readReq.put(DmaRequest {pointer: streamWrPointer, offset: 0, burstLen: 1, tag: 1});
   endmethod

   method Action getStateDbg();
      indication.reportStateDbg(srcGen, streamRdCnt, streamWrCnt, writeInProg ? 32'd1 : 32'd0, dataMismatch  ? 32'd1 : 32'd0);
   endmethod

endmodule


add separate methods for first and last pointers of both rings.  Can probably just wire up the lower methods, but what about the truncate?

// 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 FIFO::*;
import FIFOF::*;
import BRAMFIFO::*;
import GetPut::*;
import StmtFSM::*;
import ClientServer::*;

import PortalMemory::*;
import Dma::*;
import GetPutF::*;

import RingTypes::*;
import RingBuffer::*;
import CopyEngine::*;
import EchoEngine::*;
import NopEngine::*;

interface RingRequest;
   method Action set(Bit#(1) cmd, Bit#(3) regist, Bit#(64) addr);
   method Action setCmdLast(Bit#(64) addr);
   method Action setCmdFirst(Bit#(64) addr);
   method Action setStatusLast(Bit#(64) addr);
   method Action setStatusFirst(Bit#(64) addr);
   method Action get(Bit#(1) cmd, Bit#(3) regist);
   method Action hwenable(Bit#(1) en);
   method Action doCommandIndirect(Bit#(64) pointer, Bit#(64) addr);
   method Action doCommandImmediate(Bit#(64) data);
endinterface

interface RingIndication;
   method Action setResult(Bit#(1) cmd, Bit#(3) regist, Bit#(64) addr);
   method Action getResult(Bit#(1) cmd, Bit#(3) regist, Bit#(64) addr);
endinterface

module mkRingRequest#(RingIndication indication,
		      DmaReadServer#(64) dma_read_chan,
		      DmaWriteServer#(64) dma_write_chan,
		      DmaReadServer#(64) cmd_read_chan,
		      DmaWriteServer#(64) status_write_chan )(RingRequest);

   ServerF#(Bit#(64), Bit#(64)) copyEngine <- mkCopyEngine(dma_read_chan, dma_write_chan);
   ServerF#(Bit#(64), Bit#(64)) nopEngine <- mkNopEngine();
   ServerF#(Bit#(64), Bit#(64)) echoEngine <- mkEchoEngine();

   RingBuffer cmdRing <- mkRingBuffer;
   RingBuffer statusRing <- mkRingBuffer;
   Reg#(Bool) hwenabled <- mkReg(False);
   Reg#(Bool) cmdBusy <- mkReg(False);
   Reg#(DmaData#(64)) cmd <- mkReg(DmaData{data:0, tag:0});
   Reg#(Bit#(4)) ii <- mkReg(0);
   Reg#(Bit#(4)) respCtr <- mkReg(0);
   Reg#(Bit#(4)) dispCtr <- mkReg(0);
   Reg#(Bit#(6)) cmdFetchTag <- mkReg(0);
   Reg#(Bit#(6)) statusTag <- mkReg(0);
   Reg#(Bool) cmdFetchEn <- mkReg(False);

   let engineselect = cmd.data[63:56];
   function ServerF#(Bit#(64), Bit#(64)) cmdifc();
      if (engineselect == zeroExtend(pack(CmdNOP)))
	 return nopEngine;
      else if (engineselect == zeroExtend(pack(CmdCOPY)))
	 return copyEngine;
      else if (engineselect == zeroExtend(pack(CmdECHO)))
	 return echoEngine;
      else
	 return nopEngine;
   endfunction

   Stmt cmdFetch =
   seq
//      $display("cmdFetch FSM TOP");
      while (True)
	 seq
	    if (hwenabled)
	       seq
	       if (cmdRing.bufferfirst != cmdRing.bufferlast)
		  seq
		     $display ("cmdFetch handle=%h address=%h burst=%h tag=%h", cmdRing.mempointer, cmdRing.bufferlast, 8, cmdFetchTag);
		     cmd_read_chan.readReq.put(
			DmaRequest{pointer: cmdRing.mempointer,
			   offset: cmdRing.bufferlast, burstLen: 8, tag: cmdFetchTag});
		     cmdRing.pop(64);
		     cmdFetchTag <= cmdFetchTag + 1;
		  endseq
	       endseq
	 endseq
   endseq;

   Stmt cmdDispatch =
   seq
      while (True) seq
//	 $display("cmdDispatch FSM TOP");
	 seq
	    action
	       let rv <- cmd_read_chan.readData.get();
	       cmd <= rv;
	    endaction
	    // wait a cycle so cmd is valid!
	    $display("cmdDispatch 0 tag=%h %h", cmd.tag, cmd.data);
	    cmdifc.request.put(cmd.data);
	 endseq
	 for (dispCtr <= 1; dispCtr < 8; dispCtr <= dispCtr + 1)
	    action
	       let rv <- cmd_read_chan.readData.get();
	       $display("  cmdDispatch %h tag=%h %h", dispCtr, rv.tag, rv.data);
	       cmdifc.request.put(rv.data);
	    endaction
      endseq
   endseq;

   Stmt responseArbiter =
   seq
      while(True) seq
	 if (statusRing.notFull() && copyEngine.response.notEmpty())
	    seq
	       $display("responseArbiter copyEngine completion");
	       $display("status write handle=%d address=%h burst=%h tag=%h",
		  statusRing.mempointer, statusRing.bufferfirst, 8, statusTag);
	       status_write_chan.writeReq.put(
		  DmaRequest{pointer: statusRing.mempointer,
		     offset: statusRing.bufferfirst, burstLen: 8, tag: statusTag});
	       for (respCtr <= 0; respCtr < 8; respCtr <= respCtr + 1)
		  action
		     let rv <- copyEngine.response.get();
		     status_write_chan.writeData.put(DmaData{data: rv, tag: statusTag});
		  endaction
	       statusRing.push(64);
	       statusTag <= statusTag + 1;
	    endseq

	 if (statusRing.notFull() && echoEngine.response.notEmpty())
	    seq
	       $display("responseArbiter echoEngine completion");
	       $display("status write handle=%d address=%h burst=%h tag=%h",
		  statusRing.mempointer, statusRing.bufferfirst, 8, statusTag);
	       status_write_chan.writeReq.put(
		  DmaRequest{pointer: statusRing.mempointer,
		     offset: statusRing.bufferfirst, burstLen: 8, tag: statusTag});
	       for (respCtr <= 0; respCtr < 8; respCtr <= respCtr + 1)
		  action
		     let rv <- echoEngine.response.get();
		     status_write_chan.writeData.put(DmaData{data: rv, tag: statusTag});
		  endaction
	       statusRing.push(64);
	       statusTag <= statusTag + 1;
	    endseq

      endseq
   endseq;

   rule writeAck;
      let tag <- status_write_chan.writeDone.get();
      //$display("status write done tag=%h", tag);
   endrule

   mkAutoFSM (cmdFetch);
   mkAutoFSM (cmdDispatch);
   mkAutoFSM (responseArbiter);

      // to start a command, doCommand fires off a memory read to the
      // specified address. when it comes back, the doCommandRule will
      // handle it
      method Action doCommandIndirect(Bit#(64) pointer, Bit#(64) addr);
	 cmd_read_chan.readReq.put(
				   DmaRequest{pointer: truncate(pointer),
	 offset: truncate(addr), burstLen: 8, tag: cmdFetchTag});
   	 cmdFetchTag <= cmdFetchTag + 1;
      endmethod

      method Action doCommandImmediate(Bit#(64) data);
      	 $display("doCommandImmediate %h", data);
      endmethod

      method Action set(Bit#(1) _cmd, Bit#(3) regist, Bit#(64) addr);
	 if (_cmd == 0)
	    cmdRing.configifc.set(regist, truncate(addr));
	 else
	    statusRing.configifc.set(regist, truncate(addr));
	 indication.setResult(_cmd, regist, addr);
      endmethod

      method Action setCmdFirst(Bit#(64) addr);
	    cmdRing.configifc.setFirst(truncate(addr));
      endmethod

      method Action setStatusFirst(Bit#(64) addr);
	    statusRing.configifc.setFirst(truncate(addr));
      endmethod

      method Action setCmdLast(Bit#(64) addr);
	    cmdRing.configifc.setLast(truncate(addr));
      endmethod

      method Action setStatusLast(Bit#(64) addr);
	    statusRing.configifc.setLast(truncate(addr));
      endmethod

      method Action get(Bit#(1) _cmd, Bit#(3) regist);
	 if (_cmd == 0)
	    indication.getResult(0, regist,
	       zeroExtend(cmdRing.configifc.get(regist)));
	 else
	    indication.getResult(0, regist,
	       zeroExtend(statusRing.configifc.get(regist)));
      endmethod

      method Action hwenable(Bit#(1) en);
	 $display ("hwenable set to %h", en);
	 hwenabled <= en == 1;
      endmethod

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 FIFO::*;
import FIFOF::*;
import BRAMFIFO::*;
import GetPut::*;
import StmtFSM::*;
import ClientServer::*;

import PortalMemory::*;
import Dma::*;
import GetPutF::*;

import RingTypes::*;
import RingBuffer::*;
import CopyEngine::*;
import EchoEngine::*;
import NopEngine::*;

interface RingRequest;
   method Action set(Bit#(1) cmd, Bit#(3) regist, Bit#(64) addr);
   method Action get(Bit#(1) cmd, Bit#(3) regist);
   method Action hwenable(Bit#(1) en);
   method Action doCommandIndirect(Bit#(64) pointer, Bit#(64) addr);
   method Action doCommandImmediate(Bit#(64) data);
endinterface

interface RingIndication;
   method Action setResult(Bit#(1) cmd, Bit#(3) regist, Bit#(64) addr);
   method Action getResult(Bit#(1) cmd, Bit#(3) regist, Bit#(64) addr);
endinterface

module mkRingRequest#(RingIndication indication,
		      DmaReadServer#(64) dma_read_chan,
		      DmaWriteServer#(64) dma_write_chan,
		      DmaReadServer#(64) cmd_read_chan,
		      DmaWriteServer#(64) status_write_chan )(RingRequest);

   ServerF#(Bit#(64), Bit#(64)) copyEngine <- mkCopyEngine(dma_read_chan, dma_write_chan);
   ServerF#(Bit#(64), Bit#(64)) nopEngine <- mkNopEngine();
   ServerF#(Bit#(64), Bit#(64)) echoEngine <- mkEchoEngine();

   RingBuffer cmdRing <- mkRingBuffer;
   RingBuffer statusRing <- mkRingBuffer;
   Reg#(Bool) hwenabled <- mkReg(False);
   Reg#(Bool) cmdBusy <- mkReg(False);
   Reg#(DmaData#(64)) cmd <- mkReg(DmaData{data:0, tag:0});
   Reg#(Bit#(4)) ii <- mkReg(0);
   Reg#(Bit#(4)) respCtr <- mkReg(0);
   Reg#(Bit#(4)) dispCtr <- mkReg(0);
   Reg#(Bit#(6)) cmdFetchTag <- mkReg(0);
   Reg#(Bit#(6)) statusTag <- mkReg(0);
   Reg#(Bool) cmdFetchEn <- mkReg(False);

   let engineselect = cmd.data[63:56];
   function ServerF#(Bit#(64), Bit#(64)) cmdifc();
      if (engineselect == zeroExtend(pack(CmdNOP)))
	 return nopEngine;
      else if (engineselect == zeroExtend(pack(CmdCOPY)))
	 return copyEngine;
      else if (engineselect == zeroExtend(pack(CmdECHO)))
	 return echoEngine;
      else
	 return nopEngine;
   endfunction

   Stmt cmdFetch =
   seq
//      $display("cmdFetch FSM TOP");
      while (True)
	 seq
	    if (hwenabled)
	       seq
	       if (cmdRing.bufferfirst != cmdRing.bufferlast)
		  seq
		     $display ("cmdFetch handle=%h address=%h burst=%h tag=%h", cmdRing.mempointer, cmdRing.bufferlast, 8, cmdFetchTag);
		     cmd_read_chan.readReq.put(
			DmaRequest{pointer: cmdRing.mempointer,
			   offset: cmdRing.bufferlast, burstLen: 8, tag: cmdFetchTag});
		     cmdRing.pop(64);
		     cmdFetchTag <= cmdFetchTag + 1;
		  endseq
	       endseq
	 endseq
   endseq;

   Stmt cmdDispatch =
   seq
      while (True) seq
//	 $display("cmdDispatch FSM TOP");
	 seq
	    action
	       let rv <- cmd_read_chan.readData.get();
	       cmd <= rv;
	    endaction
	    // wait a cycle so cmd is valid!
	    $display("cmdDispatch 0 tag=%h %h", cmd.tag, cmd.data);
	    cmdifc.request.put(cmd.data);
	 endseq
	 for (dispCtr <= 1; dispCtr < 8; dispCtr <= dispCtr + 1)
	    action
	       let rv <- cmd_read_chan.readData.get();
	       $display("  cmdDispatch %h tag=%h %h", dispCtr, rv.tag, rv.data);
	       cmdifc.request.put(rv.data);
	    endaction
      endseq
   endseq;

   Stmt responseArbiter =
   seq
      while(True) seq
	 if (statusRing.notFull() && copyEngine.response.notEmpty())
	    seq
	       $display("responseArbiter copyEngine completion");
	       $display("status write handle=%d address=%h burst=%h tag=%h",
		  statusRing.mempointer, statusRing.bufferfirst, 8, statusTag);
	       status_write_chan.writeReq.put(
		  DmaRequest{pointer: statusRing.mempointer,
		     offset: statusRing.bufferfirst, burstLen: 8, tag: statusTag});
	       for (respCtr <= 0; respCtr < 8; respCtr <= respCtr + 1)
		  action
		     let rv <- copyEngine.response.get();
		     status_write_chan.writeData.put(DmaData{data: rv, tag: statusTag});
		  endaction
	       statusRing.push(64);
	       statusTag <= statusTag + 1;
	    endseq

	 if (statusRing.notFull() && echoEngine.response.notEmpty())
	    seq
	       $display("responseArbiter echoEngine completion");
	       $display("status write handle=%d address=%h burst=%h tag=%h",
		  statusRing.mempointer, statusRing.bufferfirst, 8, statusTag);
	       status_write_chan.writeReq.put(
		  DmaRequest{pointer: statusRing.mempointer,
		     offset: statusRing.bufferfirst, burstLen: 8, tag: statusTag});
	       for (respCtr <= 0; respCtr < 8; respCtr <= respCtr + 1)
		  action
		     let rv <- echoEngine.response.get();
		     status_write_chan.writeData.put(DmaData{data: rv, tag: statusTag});
		  endaction
	       statusRing.push(64);
	       statusTag <= statusTag + 1;
	    endseq

      endseq
   endseq;

   rule writeAck;
      let tag <- status_write_chan.writeDone.get();
      //$display("status write done tag=%h", tag);
   endrule

   mkAutoFSM (cmdFetch);
   mkAutoFSM (cmdDispatch);
   mkAutoFSM (responseArbiter);

      // to start a command, doCommand fires off a memory read to the
      // specified address. when it comes back, the doCommandRule will
      // handle it
      method Action doCommandIndirect(Bit#(64) pointer, Bit#(64) addr);
	 cmd_read_chan.readReq.put(
				   DmaRequest{pointer: truncate(pointer),
	 offset: truncate(addr), burstLen: 8, tag: cmdFetchTag});
   	 cmdFetchTag <= cmdFetchTag + 1;
      endmethod

      method Action doCommandImmediate(Bit#(64) data);
      	 $display("doCommandImmediate %h", data);
      endmethod

      method Action set(Bit#(1) _cmd, Bit#(3) regist, Bit#(64) addr);
	 if (_cmd == 0)
	    cmdRing.configifc.set(regist, truncate(addr));
	 else
	    statusRing.configifc.set(regist, truncate(addr));
	 indication.setResult(_cmd, regist, addr);
      endmethod

      method Action get(Bit#(1) _cmd, Bit#(3) regist);
	 if (_cmd == 0)
	    indication.getResult(0, regist,
	       zeroExtend(cmdRing.configifc.get(regist)));
	 else
	    indication.getResult(0, regist,
	       zeroExtend(statusRing.configifc.get(regist)));
      endmethod

      method Action hwenable(Bit#(1) en);
	 $display ("hwenable set to %h", en);
	 hwenabled <= en == 1;
      endmethod

endmodule


Fix irqSet EHR scheduling

Fix irqSet EHR scheduling

interface InterruptSenderWires;
	(* always_ready, prefix="", result="ins" *)
	method Bit#(1) ins;
endinterface

interface InterruptSender;
	interface WriteOnly#(Bool) enabled;
	method Action send;
	method Action clear;

	interface InterruptSenderWires irqWires;
endinterface

module mkInterruptSender(InterruptSender);
	Array#(Reg#(Bool)) irqSet <- mkCReg(2,False);
	Reg#(Bool) irqEnabled <- mkReg(False);

	interface WriteOnly enabled;
		method Action _write(Bool x) = irqEnabled._write(x);
	endinterface

	method Action send;
		irqSet[1] <= True;
	endmethod
	method Action clear;
		irqSet[0] <= False;
	endmethod

	interface InterruptSenderWires irqWires;
		method Bit#(1) ins = irqEnabled && irqSet[0] ? 1 : 0;
	endinterface
endmodule

interface InterruptSenderWires;
	(* always_ready, prefix="", result="ins" *)
	method Bit#(1) ins;
endinterface

interface InterruptSender;
	interface WriteOnly#(Bool) enabled;
	method Action send;
	method Action clear;

	interface InterruptSenderWires irqWires;
endinterface

module mkInterruptSender(InterruptSender);
	Array#(Reg#(Bool)) irqSet <- mkCReg(2,False);
	Reg#(Bool) irqEnabled <- mkReg(False);

	interface WriteOnly enabled;
		method Action _write(Bool x) = irqEnabled._write(x);
	endinterface

	method Action send;
		irqSet[1] <= True;
	endmethod
	method Action clear;
		irqSet[0] <= False;
	endmethod

	interface InterruptSenderWires irqWires;
		method Bit#(1) ins = irqEnabled && irqSet[1] ? 1 : 0;
	endinterface
endmodule