rename signals, still have to deal with resets and clocks

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

// 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 "txo"
// Hopefully this is what importbvi.py would do
(* always_ready, always_enabled *)
interface Par_txo;
   method Action data_p(Bit#(8) v);
   method Action data_n(Bit#(8) v);
   method Action frame_p(Bit#(1) v);
   method Action frame_n(Bit#(1) v);
   method Action lclk_p(Bit#(1) v);
   method Action lclk_n(Bit#(1) v);
endinterface

(* always_ready, always_enabled *)
interface Par_txi;
   method Bit#(1) wr_wait_p();
   method Bit#(1) wr_wait_n();
   method Bit#(1) rd_wait_p();
   method Bit#(1) rd_wait_n();
endinterface

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

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

(* always_ready, always_enabled *)
interface Par_misc;
   method Bit#(1) csysack();
   method Bit#(1) cactive();
   method Action csysreq(Bit#(1) v);
   method Bit#(1) reset_chip();
   method Bit#(1) reset_fpga();
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(esaxi_aclk) = saxiclk;  // assigns the verilog esaxi_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);
   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();
      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_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 esaxi_araddr araddr() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_arburst arburst() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_arcache arcache() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_aresetn aresetn() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_arid arid() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_arlen arlen() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_arlock arlock() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_arprot arprot() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_arqos arqos() clocked_by (saxiclk) reset_by(saxireset);
      method arready(esaxi_arready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_arready);
      method esaxi_arsize arsize() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_arvalid arvalid() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awaddr awaddr() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awburst awburst() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awcache awcache() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awid awid() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awlen awlen() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awlock awlock() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awprot awprot() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awqos awqos() clocked_by (saxiclk) reset_by(saxireset);
      method awready(esaxi_awready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_awready);
      method esaxi_awsize awsize() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_awvalid awvalid() clocked_by (saxiclk) reset_by(saxireset);
      method bid(esaxi_bid) enable((*inhigh*) EN_esaxi_bid);
      method esaxi_bready bready() clocked_by (saxiclk) reset_by(saxireset);
      method bresp(esaxi_bresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_bresp);
      method bvalid(esaxi_bvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_bvalid);
      method rdata(esaxi_rdata)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rdata);
      method rid(esaxi_rid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rid);
      method rlast(esaxi_rlast)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rlast);
      method esaxi_rready rready() clocked_by (saxiclk) reset_by(saxireset);
      method rresp(esaxi_rresp)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rresp);
      method rvalid(esaxi_rvalid)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_rvalid);
      method esaxi_wdata wdata() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_wid wid() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_wlast wlast() clocked_by (saxiclk) reset_by(saxireset);
      method wready(esaxi_wready)  clocked_by (saxiclk) reset_by(saxireset) enable((*inhigh*) EN_esaxi_wready);
      method esaxi_wstrb wstrb() clocked_by (saxiclk) reset_by(saxireset);
      method esaxi_wvalid wvalid() clocked_by (saxiclk) reset_by(saxireset);
   endinterface

   interface ParMaxiGp maxi;
      method araddr(emaxi_araddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_araddr);
      method arburst(emaxi_arburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arburst);
      method arcache(emaxi_arcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arcache);
      method emaxi_aresetn aresetn() clocked_by(maxiclk) reset_by(maxireset);
      method arid(emaxi_arid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arid);
      method arlen(emaxi_arlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arlen);
      method arlock(emaxi_arlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arlock);
      method arprot(emaxi_arprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arprot);
      method arqos(emaxi_arqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arqos);
      method emaxi_arready arready() clocked_by(maxiclk) reset_by(maxireset);
      method arsize(emaxi_arsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arsize);
      method arvalid(emaxi_arvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_arvalid);
      method awaddr(emaxi_awaddr) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awaddr);
      method awburst(emaxi_awburst) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awburst);
      method awcache(emaxi_awcache) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awcache);
      method awid(emaxi_awid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awid);
      method awlen(emaxi_awlen) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awlen);
      method awlock(emaxi_awlock) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awlock);
      method awprot(emaxi_awprot) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awprot);
      method awqos(emaxi_awqos) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awqos);
      method emaxi_awready awready() clocked_by(maxiclk) reset_by(maxireset);
      method awsize(emaxi_awsize) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awsize);
      method awvalid(emaxi_awvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_awvalid);
      method emaxi_bid bid() clocked_by(maxiclk) reset_by(maxireset);
      method bready(emaxi_bready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_bready);
      method emaxi_bresp bresp() clocked_by(maxiclk) reset_by(maxireset);
      method emaxi_bvalid bvalid() clocked_by(maxiclk) reset_by(maxireset);
      method emaxi_rdata rdata() clocked_by(maxiclk) reset_by(maxireset);
      method emaxi_rlast rlast() clocked_by(maxiclk) reset_by(maxireset);
      method rready(emaxi_rready) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_rready);
      method emaxi_rresp rresp() clocked_by(maxiclk) reset_by(maxireset);
      method emaxi_rvalid rvalid() clocked_by(maxiclk) reset_by(maxireset);
      method wdata(emaxi_wdata) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wdata);
      method wid(emaxi_wid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wid);
      method wlast(emaxi_wlast) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wlast);
      method emaxi_wready wready() clocked_by(maxiclk) reset_by(maxireset);
      method wstrb(emaxi_wstrb) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wstrb);
      method wvalid(emaxi_wvalid) clocked_by(maxiclk) reset_by(maxireset) enable((*inhigh*) EN_emaxi_wvalid);
      method emaxi_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


added instance ConnectableWithClocks#(Axi3Master#(addrWidth, busWidth,idWidth), Axi3Slave#(addrWidth, busWidth,idWidth))

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

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

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

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

import FIFOF::*;
import FIFO::*;
import GetPut::*;
import GetPutWithClocks::*;
import Connectable::*;
import RegFile::*;

typeclass RegToWriteOnly#(type a);
   function WriteOnly#(a) regToWriteOnly(Reg#(a) x);
endtypeclass

instance RegToWriteOnly#(a);
   function WriteOnly#(a) regToWriteOnly(Reg#(a) x);
      return (interface WriteOnly;
		 method Action _write(a v);
		    x._write(v);
		 endmethod
	      endinterface);
   endfunction
endinstance

typedef struct {
   Bit#(addrWidth) address;
   Bit#(4) len;
   Bit#(3) size; // assume matches bus width of Axi3Master
   Bit#(2) burst;  // drive with 2'b01
   Bit#(3) prot; // drive with 3'b000
   Bit#(4) cache; // drive with 4'b0011
   Bit#(idWidth) id;
   Bit#(2) lock;
   Bit#(4) qos;
} Axi3ReadRequest#(numeric type addrWidth, numeric type idWidth) deriving (Bits);

function Bit#(3) axiBusSize(Integer busWidth);
   if (busWidth == 32)
      return 3'b010; // 3'b010: 32bit, 3'b011: 64bit, 3'b100: 128bit
   else if (busWidth == 64)
      return 3'b011;
   else if (busWidth == 128)
      return 3'b100;
   else
      return 3'b011;
endfunction

typedef struct {
   Bit#(busWidth) data;
   Bit#(2) resp;
   Bit#(1) last;
   Bit#(idWidth) id;
} Axi3ReadResponse#(numeric type busWidth, numeric type idWidth) deriving (Bits);

typedef struct {
   Bit#(addrWidth) address;
   Bit#(4) len;
   Bit#(3) size; // assume matches bus width of Axi3Master
   Bit#(2) burst;  // drive with 2'b01
   Bit#(3) prot; // drive with 3'b000
   Bit#(4) cache; // drive with 4'b0011
   Bit#(idWidth) id;
   Bit#(2) lock;
   Bit#(4) qos;
} Axi3WriteRequest#(numeric type addrWidth, numeric type idWidth) deriving (Bits);

typedef struct {
    Bit#(busWidth) data;
    Bit#(TDiv#(busWidth,8)) byteEnable;
    Bit#(1)        last;
    Bit#(idWidth) id;
} Axi3WriteData#(numeric type busWidth, numeric type idWidth) deriving (Bits);

typedef struct {
    Bit#(2) resp;
    Bit#(idWidth) id;
} Axi3WriteResponse#(numeric type idWidth) deriving (Bits);

function Get#(Axi3ReadResponse#(_b,_c)) get_resp_read(Axi3Slave#(_a,_b,_c) x);
   return x.resp_read;
endfunction

function Get#(Axi3WriteResponse#(_c)) get_resp_b(Axi3Slave#(_a,_b,_c) x);
   return x.resp_b;
endfunction

interface Axi3Master#(numeric type addrWidth, numeric type busWidth, numeric type idWidth);
   interface Get#(Axi3ReadRequest#(addrWidth, idWidth)) req_ar;
   interface Put#(Axi3ReadResponse#(busWidth, idWidth)) resp_read;
   interface Get#(Axi3WriteRequest#(addrWidth, idWidth)) req_aw;
   interface Get#(Axi3WriteData#(busWidth, idWidth)) resp_write;
   interface Put#(Axi3WriteResponse#(idWidth)) resp_b;
endinterface

interface Axi3Slave#(numeric type addrWidth, numeric type busWidth, numeric type idWidth);
   interface Put#(Axi3ReadRequest#(addrWidth, idWidth)) req_ar;
   interface Get#(Axi3ReadResponse#(busWidth, idWidth)) resp_read;
   interface Put#(Axi3WriteRequest#(addrWidth, idWidth)) req_aw;
   interface Put#(Axi3WriteData#(busWidth, idWidth)) resp_write;
   interface Get#(Axi3WriteResponse#(idWidth)) resp_b;
endinterface

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

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

function  Axi3Master#(addrWidth, busWidth, idWidth) null_axi_master();
   return (interface Axi3Master;
	      interface Get req_ar = null_get;
	      interface Put resp_read = null_put;
	      interface Get req_aw = null_get;
	      interface Get resp_write = null_get;
	      interface Put resp_b = null_put;
	   endinterface);
endfunction

instance Connectable#(Axi3Master#(addrWidth, busWidth,idWidth), Axi3Slave#(addrWidth, busWidth,idWidth));
   module mkConnection#(Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s)(Empty);

      mkConnection(m.req_ar, s.req_ar);
      mkConnection(s.resp_read, m.resp_read);

      mkConnection(m.req_aw, s.req_aw);
      mkConnection(m.resp_write, s.resp_write);
      mkConnection(s.resp_b, m.resp_b);

   endmodule
endinstance

instance ConnectableWithClocks#(Axi3Master#(addrWidth, busWidth,idWidth), Axi3Slave#(addrWidth, busWidth,idWidth))
   provisos (ConnectableWithClocks#(Get#(Axi3ReadRequest#(addrWidth, idWidth)), Put#(Axi3ReadRequest#(addrWidth, idWidth)))
	     ,ConnectableWithClocks#(Get#(Axi3ReadResponse#(busWidth, idWidth)), Put#(Axi3ReadResponse#(busWidth, idWidth)))
	     ,ConnectableWithClocks#(Get#(Axi3WriteRequest#(addrWidth, idWidth)), Put#(Axi3WriteRequest#(addrWidth, idWidth)))
	     ,ConnectableWithClocks#(Get#(Axi3WriteData#(busWidth, idWidth)), Put#(Axi3WriteData#(busWidth, idWidth)))
	     ,ConnectableWithClocks#(Get#(Axi3WriteResponse#(idWidth)), Put#(Axi3WriteResponse#(idWidth)))
	     );

   module mkConnectionWithClocks2#(Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s)(Empty);
      mkConnectionWithClocks(clockOf(m), resetOf(m), clockOf(s), resetOf(s), m, s);
   endmodule

   module mkConnectionWithClocks#(Clock mClock, Reset mReset, Clock sClock, Reset sReset,
				  Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s)(Empty);

      mkConnectionWithClocks(mClock, mReset, sClock, sReset, m.req_ar, s.req_ar);
      mkConnectionWithClocks(sClock, sReset, mClock, mReset, s.resp_read, m.resp_read);

      mkConnectionWithClocks(mClock, mReset, sClock, sReset, m.req_aw, s.req_aw);
      mkConnectionWithClocks(mClock, mReset, sClock, sReset, m.resp_write, s.resp_write);
      mkConnectionWithClocks(sClock, sReset, mClock, mReset, s.resp_b, m.resp_b);

   endmodule
endinstance

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

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

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

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

import FIFOF::*;
import FIFO::*;
import GetPut::*;
import Connectable::*;
import RegFile::*;

typeclass RegToWriteOnly#(type a);
   function WriteOnly#(a) regToWriteOnly(Reg#(a) x);
endtypeclass

instance RegToWriteOnly#(a);
   function WriteOnly#(a) regToWriteOnly(Reg#(a) x);
      return (interface WriteOnly;
		 method Action _write(a v);
		    x._write(v);
		 endmethod
	      endinterface);
   endfunction
endinstance

typedef struct {
   Bit#(addrWidth) address;
   Bit#(4) len;
   Bit#(3) size; // assume matches bus width of Axi3Master
   Bit#(2) burst;  // drive with 2'b01
   Bit#(3) prot; // drive with 3'b000
   Bit#(4) cache; // drive with 4'b0011
   Bit#(idWidth) id;
   Bit#(2) lock;
   Bit#(4) qos;
} Axi3ReadRequest#(numeric type addrWidth, numeric type idWidth) deriving (Bits);

function Bit#(3) axiBusSize(Integer busWidth);
   if (busWidth == 32)
      return 3'b010; // 3'b010: 32bit, 3'b011: 64bit, 3'b100: 128bit
   else if (busWidth == 64)
      return 3'b011;
   else if (busWidth == 128)
      return 3'b100;
   else
      return 3'b011;
endfunction

typedef struct {
   Bit#(busWidth) data;
   Bit#(2) resp;
   Bit#(1) last;
   Bit#(idWidth) id;
} Axi3ReadResponse#(numeric type busWidth, numeric type idWidth) deriving (Bits);

typedef struct {
   Bit#(addrWidth) address;
   Bit#(4) len;
   Bit#(3) size; // assume matches bus width of Axi3Master
   Bit#(2) burst;  // drive with 2'b01
   Bit#(3) prot; // drive with 3'b000
   Bit#(4) cache; // drive with 4'b0011
   Bit#(idWidth) id;
   Bit#(2) lock;
   Bit#(4) qos;
} Axi3WriteRequest#(numeric type addrWidth, numeric type idWidth) deriving (Bits);

typedef struct {
    Bit#(busWidth) data;
    Bit#(TDiv#(busWidth,8)) byteEnable;
    Bit#(1)        last;
    Bit#(idWidth) id;
} Axi3WriteData#(numeric type busWidth, numeric type idWidth) deriving (Bits);

typedef struct {
    Bit#(2) resp;
    Bit#(idWidth) id;
} Axi3WriteResponse#(numeric type idWidth) deriving (Bits);

function Get#(Axi3ReadResponse#(_b,_c)) get_resp_read(Axi3Slave#(_a,_b,_c) x);
   return x.resp_read;
endfunction

function Get#(Axi3WriteResponse#(_c)) get_resp_b(Axi3Slave#(_a,_b,_c) x);
   return x.resp_b;
endfunction

interface Axi3Master#(numeric type addrWidth, numeric type busWidth, numeric type idWidth);
   interface Get#(Axi3ReadRequest#(addrWidth, idWidth)) req_ar;
   interface Put#(Axi3ReadResponse#(busWidth, idWidth)) resp_read;
   interface Get#(Axi3WriteRequest#(addrWidth, idWidth)) req_aw;
   interface Get#(Axi3WriteData#(busWidth, idWidth)) resp_write;
   interface Put#(Axi3WriteResponse#(idWidth)) resp_b;
endinterface

interface Axi3Slave#(numeric type addrWidth, numeric type busWidth, numeric type idWidth);
   interface Put#(Axi3ReadRequest#(addrWidth, idWidth)) req_ar;
   interface Get#(Axi3ReadResponse#(busWidth, idWidth)) resp_read;
   interface Put#(Axi3WriteRequest#(addrWidth, idWidth)) req_aw;
   interface Put#(Axi3WriteData#(busWidth, idWidth)) resp_write;
   interface Get#(Axi3WriteResponse#(idWidth)) resp_b;
endinterface

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

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

function  Axi3Master#(addrWidth, busWidth, idWidth) null_axi_master();
   return (interface Axi3Master;
	      interface Get req_ar = null_get;
	      interface Put resp_read = null_put;
	      interface Get req_aw = null_get;
	      interface Get resp_write = null_get;
	      interface Put resp_b = null_put;
	   endinterface);
endfunction

instance Connectable#(Axi3Master#(addrWidth, busWidth,idWidth), Axi3Slave#(addrWidth, busWidth,idWidth));
   module mkConnection#(Axi3Master#(addrWidth, busWidth,idWidth) m, Axi3Slave#(addrWidth, busWidth,idWidth) s)(Empty);

      mkConnection(m.req_ar, s.req_ar);
      mkConnection(s.resp_read, m.resp_read);

      mkConnection(m.req_aw, s.req_aw);
      mkConnection(m.resp_write, s.resp_write);
      mkConnection(s.resp_b, m.resp_b);

   endmodule
endinstance


clean up Dtp.bsv

clean up Dtp.bsv

// Copyright (c) 2014 Cornell University.

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

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

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

package Dtp;

import FIFO::*;
import FIFOF::*;
import SpecialFIFOs::*;
import Vector::*;
import GetPut::*;
import ClientServer::*;
import FShow::*;
import Probe::*;
import Pipe::*;
import Ethernet::*;
//import MemTypes::*;

typedef 54 TIMESTAMP_LEN;
typedef 4  N_IFCs;

typedef 8  CmdLen;
typedef 32 ParamLen;

typedef 3 GLOBAL_DELAY;

typedef struct {
   Bit#(CmdLen)   cmd;
   Bit#(ParamLen) param;
} CmdTup deriving (Eq, Bits, FShow);

typedef struct {
   Bool     mux_sel;
   Bit#(53) c_local;
   Bit#(1)  parity;
} TxStageOneBuf deriving (Eq, Bits);

interface Dtp;
   interface PipeIn#(Bit#(66))  dtpRxIn;
   interface PipeIn#(Bit#(66))  dtpTxIn;
   interface PipeOut#(Bit#(66)) dtpRxOut;
   interface PipeOut#(Bit#(66)) dtpTxOut;
   (* always_ready, always_enabled *)
   method Action tx_ready(Bool v);
   (* always_ready, always_enabled *)
   method Action rx_ready(Bool v);
   interface DtpToPhyIfc api;
endinterface

typedef 3'b100 LOG_TYPE;
typedef 2'b01 INIT_TYPE;
typedef 2'b10 ACK_TYPE;
typedef 2'b11 BEACON_TYPE;

//FIXME: should be controlled by driver.
typedef 1000 INIT_TIMEOUT;
typedef 1000 SYNC_TIMEOUT;

typedef enum {INIT, SENT, SYNC} DtpState
deriving (Bits, Eq);

(* synthesize *)
module mkDtpTop(Dtp);
   Dtp _a <- mkDtp(0);
   return _a;
endmodule

module mkDtp#(Integer id)(Dtp);

   let verbose = False;
   Wire#(Bool) tx_ready_wire <- mkDWire(False);
   Wire#(Bool) rx_ready_wire <- mkDWire(False);

   FIFOF#(Bit#(66)) dtpRxInFifo <- mkFIFOF ();
   FIFOF#(Bit#(66)) dtpTxInFifo <- mkFIFOF ();

   Reg#(Bit#(1))   mode <- mkReg(0); // mode=0 NIC, mode=1 SWITCH
   Reg#(Bit#(32))  cycle   <- mkReg(0);
   Reg#(DtpState)  curr_state  <- mkReg(INIT);

   Reg#(Bit#(53))  c_local <- mkReg(0); //fromInteger(c_local_init));
   Reg#(Bit#(53))  delay   <- mkReg(0);
   Reg#(Bit#(32))  timeout_count_init <- mkReg(0);
   Reg#(Bit#(32))  timeout_count_sync <- mkReg(0);
   Wire#(Bool) init_rcvd    <- mkDWire(False);
   Wire#(Bool) ack_rcvd     <- mkDWire(False);
   Wire#(Bool) beacon_rcvd  <- mkDWire(False);
   Reg#(Bool) is_idle      <- mkReg(False);

   Wire#(Bit#(53)) c_local_next <- mkDWire(0);
   Wire#(Bit#(2))  tx_mux_sel   <- mkDWire(0);

   // Tx Stage 1
   FIFOF#(Bit#(66)) dtpTxInPipelineFifo <- mkFIFOF;
   FIFOF#(Bit#(66)) dtpTxOutFifo <- mkFIFOF;
   FIFOF#(TxStageOneBuf) stageOneFifo <- mkFIFOF;

   FIFOF#(Bit#(53)) outstandingInitRequest <- mkSizedFIFOF(8);

   FIFOF#(Bit#(2))  dtpEventFifo   <- mkFIFOF;
   FIFOF#(Bit#(2))  dtpEventOutputFifo   <- mkFIFOF;
   FIFOF#(Bit#(66)) dtpRxOutFifo <- mkFIFOF;

   FIFOF#(Bit#(53)) localCompareRemoteFifo  <- mkFIFOF;
   FIFOF#(Bit#(53)) localCompareGlobalFifo  <- mkFIFOF;
   FIFOF#(Bit#(53)) remoteCompareGlobalFifo <- mkFIFOF;
   FIFOF#(Bit#(53)) remoteCompareLocalFifo  <- mkFIFOF;
   FIFOF#(Bit#(53)) globalCompareRemoteFifo <- mkFIFOF;
   FIFOF#(Bit#(53)) globalCompareLocalFifo  <- mkFIFOF;

   FIFOF#(Bit#(53)) localOutputFifo  <- mkFIFOF;
   FIFOF#(Bit#(53)) globalOutputFifo <- mkFIFOF;
   FIFOF#(Bit#(53)) remoteOutputFifo <- mkFIFOF;

   FIFOF#(Bool) localLeRemoteFifo  <- mkFIFOF;
   FIFOF#(Bool) localGtRemoteFifo  <- mkFIFOF;
   FIFOF#(Bool) globalLeRemoteFifo <- mkFIFOF;
   FIFOF#(Bool) globalGtRemoteFifo <- mkFIFOF;
   FIFOF#(Bool) globalLeLocalFifo  <- mkFIFOF;
   FIFOF#(Bool) globalGtLocalFifo  <- mkFIFOF;

   FIFOF#(void) cfFifo <- mkFIFOF;
   FIFOF#(void) dmFifo <- mkFIFOF;

   Reg#(Bool)       log_rcvd     <- mkReg(False);
   FIFOF#(Bit#(53)) fromHostFifo <- mkSizedFIFOF(1);
   FIFOF#(Bit#(53)) toHostFifo   <- mkSizedFIFOF(1);
   FIFOF#(Bit#(32)) delayFifo    <- mkSizedFIFOF(1);
   FIFOF#(Bit#(32)) stateFifo     <- mkSizedFIFOF(1);

   rule cyc;
      cycle <= cycle + 1;
   endrule

   // Setup link first if neither Tx or Rx is ready, bypass DTP.
   rule tx_bypass(!tx_ready_wire || !rx_ready_wire);
      let v <- toGet(dtpTxInFifo).get;
      dtpTxOutFifo.enq(v);
   endrule

   rule rx_bypass(!tx_ready_wire || !rx_ready_wire);
      let v <- toGet(dtpRxInFifo).get;
      dtpRxOutFifo.enq(v);
   endrule

   rule tx_stage1(tx_ready_wire && rx_ready_wire);
      let v <- toGet(dtpTxInFifo).get();
      Bit#(1) parity;
      Bool    mux_sel;
      Bit#(53) c_local_out;
      c_local_out = c_local+2; // forward compute parity.
      parity = ^c_local_out[52:0];

      if(v[9:2] == 8'h1e) begin
         mux_sel = True;
         is_idle <= True;
      end
      else begin
         mux_sel = False;
         is_idle <= False;
      end

      if(verbose) $display("%d: %d dtpTxIn=%h, c_local=%h, is_idle=%h, curr_state=%d", cycle, id, v, c_local, mux_sel, curr_state);
      cfFifo.enq(?);
      dmFifo.enq(?);
      stageOneFifo.enq(TxStageOneBuf{mux_sel: mux_sel,
                                     parity: parity,
                                     c_local: c_local+1});
      dtpTxInPipelineFifo.enq(v);
   endrule

   Probe#(Bit#(53)) debug_from_host <- mkProbe();
   rule tx_stage2(tx_ready_wire && rx_ready_wire);
      let val <- toGet(stageOneFifo).get;
      let v <- toGet(dtpTxInPipelineFifo).get();
      let mux_sel = val.mux_sel;
      let c_local = val.c_local;
      let parity = val.parity;

      Bit#(10) block_type;
      Bit#(66) encodeOut;
      Bit#(3) log_type    = fromInteger(valueOf(LOG_TYPE));
      Bit#(2) init_type   = fromInteger(valueOf(INIT_TYPE));
      Bit#(2) ack_type    = fromInteger(valueOf(ACK_TYPE));
      Bit#(2) beacon_type = fromInteger(valueOf(BEACON_TYPE));

      block_type = v[9:0];

      if (mux_sel && tx_mux_sel == init_type) begin
         encodeOut = {c_local+1, parity, init_type, block_type};
         $display("Enqueued ougoing init request");
         outstandingInitRequest.enq(c_local+1);
      end
      else if (mux_sel && tx_mux_sel == ack_type) begin
         encodeOut = {c_local+1, parity, ack_type, block_type};
      end
      else if (mux_sel && tx_mux_sel == beacon_type) begin
         encodeOut = {c_local+1, parity, beacon_type, block_type};
      end
      else if (mux_sel && fromHostFifo.notEmpty) begin
         let host_data = fromHostFifo.first;
         debug_from_host <= host_data;
         encodeOut = {host_data, log_type, block_type};
         fromHostFifo.deq;
      end
      else begin
         encodeOut = v;
      end
      if(verbose) $display("%d: %d dtpTxOut=%h, c_local=%h, encodeOut=%h", cycle, id, v, c_local, encodeOut[11:10]);
      dtpTxOutFifo.enq(encodeOut);
   endrule

   // delay measurement
   rule delay_measurment(curr_state == INIT || curr_state == SENT);
      let init_timeout = fromInteger(valueOf(INIT_TIMEOUT));
      let init_type = fromInteger(valueOf(INIT_TYPE));
      let ack_type = fromInteger(valueOf(ACK_TYPE));
      dmFifo.deq;
      // Timeout driven output
      if (timeout_count_init > init_timeout) begin
         if (is_idle) begin
            timeout_count_init <= 0;
         end
         else begin
            timeout_count_init <= timeout_count_init + 1;
         end
         tx_mux_sel <= init_type;
         if(verbose) $display("%d: %d, init timed_out %d", cycle, id, timeout_count_init);
      end
      else if (init_rcvd) begin
         timeout_count_init <= timeout_count_init + 1;
         tx_mux_sel <= ack_type;
      end
      else begin
         timeout_count_init <= timeout_count_init + 1;
         tx_mux_sel <= 2'b00;
      end

      // compute delay
      if (ack_rcvd) begin
         let temp = outstandingInitRequest.first;
         delay <= (c_local - temp - 1) >> 1;
         if(verbose) $display("%d: %d update delay=%h, %h, %h", cycle, id, c_local, temp, (c_local-temp-1)>>1);
         outstandingInitRequest.deq;
      end
   endrule

   // Beacon
   rule beacon(curr_state == SYNC);
      dmFifo.deq;
      let sync_timeout = fromInteger(valueOf(SYNC_TIMEOUT));
      let beacon_type = fromInteger(valueOf(BEACON_TYPE));
      let ack_type = fromInteger(valueOf(ACK_TYPE));
      if (timeout_count_sync >= sync_timeout) begin
         if (is_idle) begin
            timeout_count_sync <= 0;
         end
         else begin
            timeout_count_sync <= timeout_count_sync + 1;
         end
         tx_mux_sel <= beacon_type;
      end
      else if (init_rcvd) begin
         tx_mux_sel <= ack_type;
         timeout_count_sync <= timeout_count_sync + 1;
      end
      else begin
         timeout_count_sync <= timeout_count_sync + 1;
         tx_mux_sel <= 2'b00;
      end

      if (ack_rcvd) begin
         let temp = outstandingInitRequest.first;
         delay <= (c_local - temp - 1) >> 1;
         if(verbose) $display("%d: %d update delay=%h, %h, %h", cycle, id, c_local, temp, (c_local-temp-1)>>1);
         outstandingInitRequest.deq;
      end
   endrule

   // DTP state machine
   rule state_init (curr_state == INIT);
      let init_type = fromInteger(valueOf(INIT_TYPE));
      cfFifo.deq;

      // update states
      if (tx_mux_sel == init_type && is_idle) begin
         curr_state <= SENT;
      end
      else if (init_rcvd) begin
         curr_state <= INIT;
      end
      else begin
         curr_state <= INIT;
      end
      //if(verbose) $display("%d: %d curr_state=%h", cycle, id, curr_state);
   endrule

   rule state_sent (curr_state == SENT);
      let init_type = fromInteger(valueOf(INIT_TYPE));
      cfFifo.deq;

      // update states
      if (init_rcvd) begin
         curr_state <= SENT;
      end
      else if (ack_rcvd) begin
         curr_state <= SYNC;
      end
      else if (tx_mux_sel == init_type) begin
         curr_state <= INIT;
      end
      else begin
         curr_state <= SENT;
      end
   endrule

   rule state_sync (curr_state == SYNC);
      cfFifo.deq;

      // update states
      if (init_rcvd) begin
         curr_state <= SYNC;
      end
      else begin
         curr_state <= SYNC;
      end
   endrule

   Probe#(Bit#(53)) debug_to_host <- mkProbe();
   // Parse received DTP frame
   // Remove DTP timestamp before passing frame to MAC.
   rule rx_stage1(tx_ready_wire && rx_ready_wire);
      let init_type   = fromInteger(valueOf(INIT_TYPE));
      let ack_type    = fromInteger(valueOf(ACK_TYPE));
      let beacon_type = fromInteger(valueOf(BEACON_TYPE));
      let log_type    = fromInteger(valueOf(LOG_TYPE));
      let v <- toGet(dtpRxInFifo).get();
      Bit#(1)  parity = ^v[65:13];
      Bit#(53) c_remote = v[65:13];
      Bit#(66) vo = v;
      Bool init_rcvd_next   = False;
      Bool ack_rcvd_next    = False;
      Bool beacon_rcvd_next = False;
      Bool log_rcvd_next    = False;
      vo[65:10] = 56'h0;

      if (v[9:2] == 8'h1e) begin
         if (v[11:10] == init_type) begin
            if (parity == v[12]) begin
               init_rcvd_next = True;
               if(verbose) $display("%d: %d init_rcvd %h %h", cycle, id, c_remote, c_local);
            end
            else begin
               $display("parity mismatch: expected %h, found %h", parity, v[12]);
            end
         end
         else if (v[11:10] == ack_type) begin
            if (parity == v[12]) begin
               ack_rcvd_next = True;
               if(verbose) $display("%d: %d ack_rcvd %h %h", cycle, id, c_remote, c_local);
            end
            else begin
               $display("parity mismatch: expected %h, found %h", parity, v[12]);
            end
         end
         else if (v[11:10] == beacon_type) begin
            if (parity == v[12]) begin
               beacon_rcvd_next = True;
               localCompareRemoteFifo.enq(c_local + 1);
               remoteCompareLocalFifo.enq(c_remote + 1);
               if(verbose) $display("%d: %d beacon_rcvd %h %h", cycle, id, c_remote, c_local);
            end
            else begin
               $display("parity mismatch: expected %h, found %h", parity, v[12]);
            end
         end
         else if (v[12:10] == log_type) begin
            // send v[65:13] to logger.
            log_rcvd_next = True;
            debug_to_host <= v[65:13];
            //FIXME: enable toHost.
            if (toHostFifo.notFull) begin
               toHostFifo.enq(v[65:13]);
            end
         end
         dtpEventFifo.enq(v[11:10]);
      end
      else begin
         dtpEventFifo.enq(2'b0);
      end
      //if(verbose) $display("%d: %d dtpRxIn=%h", cycle, id, v);
      //if(verbose) $display("%d: %d curr_state=%h", cycle, id, curr_state);
      init_rcvd   <= init_rcvd_next;
      ack_rcvd    <= ack_rcvd_next;
      beacon_rcvd <= beacon_rcvd_next;
      log_rcvd    <= log_rcvd_next;
      dtpRxOutFifo.enq(vo);
   endrule

   rule rx_stage2 (mode==0 || mode==1);
      let v_local <- toGet(localCompareRemoteFifo).get();
      let v_remote <- toGet(remoteCompareLocalFifo).get();
      if(verbose) $display("%d: %d, v_local=%h, v_remote=%h, delay=%h", cycle, id, v_local, v_remote, delay);
      if (v_local + 1 <= v_remote + delay) begin
         localLeRemoteFifo.enq(True);
         localGtRemoteFifo.enq(False);
      end
      else begin
         localLeRemoteFifo.enq(False);
         localGtRemoteFifo.enq(True);
      end
      localOutputFifo.enq(v_local + 1);
      remoteOutputFifo.enq(v_remote + 1);
   endrule

   rule compare_global_remote (mode==1);
      let global_delay = fromInteger(valueOf(GLOBAL_DELAY));
      let v_global <- toGet(globalCompareRemoteFifo).get();
      let v_remote <- toGet(remoteCompareGlobalFifo).get();
      if (v_global + global_delay <= v_remote + delay) begin
         globalLeRemoteFifo.enq(True);
         globalGtRemoteFifo.enq(False);
      end
      else begin
         globalLeRemoteFifo.enq(False);
         globalGtRemoteFifo.enq(True);
      end
      globalOutputFifo.enq(v_global);
   endrule

   rule compare_global_local (mode==1);
      let global_delay = fromInteger(valueOf(GLOBAL_DELAY));
      let v_global <- toGet(globalCompareLocalFifo).get();
      let v_local <- toGet(localCompareGlobalFifo).get();
      if (v_global + global_delay <= v_local + 1) begin
         globalLeLocalFifo.enq(True);
         globalGtLocalFifo.enq(False);
      end
      else begin
         globalLeLocalFifo.enq(False);
         globalGtLocalFifo.enq(True);
      end
   endrule

   rule rx_stage2_bypass;
      let v_event <- toGet(dtpEventFifo).get();
      dtpEventOutputFifo.enq(v_event);
   endrule

   rule rx_stage3_compute_c_local_next(mode==0);
      let vLocal <- toGet(localOutputFifo).get();
      let vRemote <- toGet(remoteOutputFifo).get();
      let useLocal <- toGet(localGtRemoteFifo).get();
      let _unused_ <- toGet(localLeRemoteFifo).get();
      if(verbose) $display("%d: %d, vLocal=%h", cycle, id, vLocal);
      if(verbose) $display("%d: %d, vRemote=%h", cycle, id, vRemote);
      if(verbose) $display("%d: %d, delay=%h", cycle, id, delay);
      if (useLocal) begin
         c_local_next <= vLocal + 1;
      end
      else begin
         c_local_next <= vRemote + delay + 1;
      end
   endrule

   rule output_switch (mode==1);
      let v_local <- toGet(localOutputFifo).get();
      let v_remote <- toGet(remoteOutputFifo).get();
      let v_global <- toGet(globalOutputFifo).get();
      let isGR <- toGet(globalGtRemoteFifo).get();
      let isGL <- toGet(globalGtLocalFifo).get();
      let isLR <- toGet(localGtRemoteFifo).get();
      let isLG <- toGet(globalLeLocalFifo).get();
      let isRG <- toGet(globalLeRemoteFifo).get();
      let isRL <- toGet(localLeRemoteFifo).get();
      let global_delay = fromInteger(valueOf(GLOBAL_DELAY));
      if (isGR && isGL) begin
         c_local_next <= v_global + global_delay;
      end
      else if (isLR && isLG) begin
         c_local_next <= v_local + 3;
      end
      else if (isRG && isRL) begin
         c_local_next <= v_remote + delay;
      end
   endrule

   rule rx_stage3;
      let v <- toGet(dtpEventOutputFifo).get();
      Bit#(2) beacon_type = fromInteger(valueOf(BEACON_TYPE));
      if (v == beacon_type) begin
         c_local <= c_local_next;
         if(verbose) $display("%d: %d c_local_next = %h", cycle, id, c_local_next);
      end
      else begin
         c_local <= c_local + 1;
      end
   endrule

   rule export_delay;
      delayFifo.enq(truncate(delay));
   endrule

   rule export_state;
      stateFifo.enq(zeroExtend(pack(curr_state)));
   endrule

   method Action tx_ready(Bool v);
      tx_ready_wire <= v;
   endmethod

   method Action rx_ready(Bool v);
      rx_ready_wire <= v;
   endmethod

   interface api = (interface DtpToPhyIfc;
      interface delayOut = toPipeOut(delayFifo);
      interface stateOut = toPipeOut(stateFifo);
      interface toHost   = toPipeOut(toHostFifo);
      interface fromHost = toPipeIn(fromHostFifo);
   endinterface);
   interface dtpRxIn = toPipeIn(dtpRxInFifo);
   interface dtpTxIn = toPipeIn(dtpTxInFifo);
   interface dtpRxOut = toPipeOut(dtpRxOutFifo);
   interface dtpTxOut = toPipeOut(dtpTxOutFifo);
endmodule
endpackage

// Copyright (c) 2014 Cornell University.

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

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

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

package Dtp;

import FIFO::*;
import FIFOF::*;
import SpecialFIFOs::*;
import Vector::*;
import GetPut::*;
import ClientServer::*;
import FShow::*;
import Probe::*;
import Pipe::*;
import Ethernet::*;
//import MemTypes::*;

typedef 54 TIMESTAMP_LEN;
typedef 4  N_IFCs;

typedef 8  CmdLen;
typedef 32 ParamLen;

typedef 3 GLOBAL_DELAY;

typedef struct {
   Bit#(CmdLen)   cmd;
   Bit#(ParamLen) param;
} CmdTup deriving (Eq, Bits, FShow);

typedef struct {
   Bool     mux_sel;
   Bit#(53) c_local;
   Bit#(1)  parity;
} TxStageOneBuf deriving (Eq, Bits);

interface Dtp;
   interface PipeIn#(Bit#(66))  dtpRxIn;
   interface PipeIn#(Bit#(66))  dtpTxIn;
   interface PipeOut#(Bit#(66)) dtpRxOut;
   interface PipeOut#(Bit#(66)) dtpTxOut;
   (* always_ready, always_enabled *)
   method Action tx_ready(Bool v);
   (* always_ready, always_enabled *)
   method Action rx_ready(Bool v);
   interface DtpToPhyIfc api;
endinterface

typedef 3'b100 LOG_TYPE;
typedef 2'b01 INIT_TYPE;
typedef 2'b10 ACK_TYPE;
typedef 2'b11 BEACON_TYPE;

//FIXME: should be controlled by driver.
typedef 1000 INIT_TIMEOUT;
typedef 1000 SYNC_TIMEOUT;

typedef enum {INIT, SENT, SYNC} DtpState
deriving (Bits, Eq);

(* synthesize *)
module mkDtpTop(Dtp);
   Dtp _a <- mkDtp(0);
   return _a;
endmodule

module mkDtp#(Integer id)(Dtp);

   let verbose = False;
   Wire#(Bool) tx_ready_wire <- mkDWire(False);
   Wire#(Bool) rx_ready_wire <- mkDWire(False);

   FIFOF#(Bit#(66)) dtpRxInFifo <- mkFIFOF ();
   FIFOF#(Bit#(66)) dtpTxInFifo <- mkFIFOF ();

   Reg#(Bit#(1))   mode <- mkReg(0); // mode=0 NIC, mode=1 SWITCH
   Reg#(Bit#(32))  cycle   <- mkReg(0);
   Reg#(DtpState)  curr_state  <- mkReg(INIT);

   Reg#(Bit#(53))  c_local <- mkReg(0); //fromInteger(c_local_init));
   Reg#(Bit#(53))  delay   <- mkReg(0);
   Reg#(Bit#(32))  timeout_count_init <- mkReg(0);
   Reg#(Bit#(32))  timeout_count_sync <- mkReg(0);
   Wire#(Bool) init_rcvd    <- mkDWire(False);
   Wire#(Bool) ack_rcvd     <- mkDWire(False);
   Wire#(Bool) beacon_rcvd  <- mkDWire(False);
   Reg#(Bool) is_idle      <- mkReg(False);

   Wire#(Bit#(53)) c_local_next <- mkDWire(0);
   Wire#(Bit#(2))  tx_mux_sel   <- mkDWire(0);

   // Tx Stage 1
   FIFOF#(Bit#(66)) dtpTxInPipelineFifo <- mkFIFOF;
   FIFOF#(Bit#(66)) dtpTxOutFifo <- mkFIFOF;
   FIFOF#(TxStageOneBuf) stageOneFifo <- mkFIFOF;

   FIFOF#(Bit#(53)) outstandingInitRequest <- mkSizedFIFOF(8);

   FIFOF#(Bit#(2))  dtpEventFifo   <- mkFIFOF;
   FIFOF#(Bit#(2))  dtpEventOutputFifo   <- mkFIFOF;
   FIFOF#(Bit#(66)) dtpRxOutFifo <- mkFIFOF;

   FIFOF#(Bit#(53)) localCompareRemoteFifo  <- mkFIFOF;
   FIFOF#(Bit#(53)) localCompareGlobalFifo  <- mkFIFOF;
   FIFOF#(Bit#(53)) remoteCompareGlobalFifo <- mkFIFOF;
   FIFOF#(Bit#(53)) remoteCompareLocalFifo  <- mkFIFOF;
   FIFOF#(Bit#(53)) globalCompareRemoteFifo <- mkFIFOF;
   FIFOF#(Bit#(53)) globalCompareLocalFifo  <- mkFIFOF;

   FIFOF#(Bit#(53)) localOutputFifo  <- mkFIFOF;
   FIFOF#(Bit#(53)) globalOutputFifo <- mkFIFOF;
   FIFOF#(Bit#(53)) remoteOutputFifo <- mkFIFOF;

   FIFOF#(Bool) localLeRemoteFifo  <- mkFIFOF;
   FIFOF#(Bool) localGtRemoteFifo  <- mkFIFOF;
   FIFOF#(Bool) globalLeRemoteFifo <- mkFIFOF;
   FIFOF#(Bool) globalGtRemoteFifo <- mkFIFOF;
   FIFOF#(Bool) globalLeLocalFifo  <- mkFIFOF;
   FIFOF#(Bool) globalGtLocalFifo  <- mkFIFOF;

   FIFOF#(void) cfFifo <- mkFIFOF;
   FIFOF#(void) dmFifo <- mkFIFOF;

   Reg#(Bool)       log_rcvd     <- mkReg(False);
   FIFOF#(Bit#(53)) fromHostFifo <- mkSizedFIFOF(1);
   FIFOF#(Bit#(53)) toHostFifo   <- mkSizedFIFOF(1);
   FIFOF#(Bit#(32)) delayFifo    <- mkSizedFIFOF(1);
   FIFOF#(Bit#(32)) stateFifo     <- mkSizedFIFOF(1);

   rule cyc;
      cycle <= cycle + 1;
   endrule

   // Setup link first if neither Tx or Rx is ready, bypass DTP.
   rule tx_bypass(!tx_ready_wire || !rx_ready_wire);
      let v <- toGet(dtpTxInFifo).get;
      dtpTxOutFifo.enq(v);
   endrule

   rule rx_bypass(!tx_ready_wire || !rx_ready_wire);
      let v <- toGet(dtpRxInFifo).get;
      dtpRxOutFifo.enq(v);
   endrule

   rule tx_stage1(tx_ready_wire && rx_ready_wire);
      let v <- toGet(dtpTxInFifo).get();
      Bit#(1) parity;
      Bool    mux_sel;
      Bit#(53) c_local_out;
      c_local_out = c_local+2; // forward compute parity.
      parity = ^c_local_out[52:0];

      if(v[9:2] == 8'h1e) begin
         mux_sel = True;
         is_idle <= True;
      end
      else begin
         mux_sel = False;
         is_idle <= False;
      end

      if(verbose) $display("%d: %d dtpTxIn=%h, c_local=%h, is_idle=%h, curr_state=%d", cycle, id, v, c_local, mux_sel, curr_state);
      cfFifo.enq(?);
      dmFifo.enq(?);
      stageOneFifo.enq(TxStageOneBuf{mux_sel: mux_sel,
                                     parity: parity,
                                     c_local: c_local+1});
      dtpTxInPipelineFifo.enq(v);
   endrule

   Probe#(Bit#(53)) debug_from_host <- mkProbe();
   rule tx_stage2(tx_ready_wire && rx_ready_wire);
      let val <- toGet(stageOneFifo).get;
      let v <- toGet(dtpTxInPipelineFifo).get();
      let mux_sel = val.mux_sel;
      let c_local = val.c_local;
      let parity = val.parity;

      Bit#(10) block_type;
      Bit#(66) encodeOut;
      Bit#(3) log_type    = fromInteger(valueOf(LOG_TYPE));
      Bit#(2) init_type   = fromInteger(valueOf(INIT_TYPE));
      Bit#(2) ack_type    = fromInteger(valueOf(ACK_TYPE));
      Bit#(2) beacon_type = fromInteger(valueOf(BEACON_TYPE));

      block_type = v[9:0];

      if (mux_sel && tx_mux_sel == init_type) begin
         encodeOut = {c_local+1, parity, init_type, block_type};
         $display("Enqueued ougoing init request");
         outstandingInitRequest.enq(c_local+1);
      end
      else if (mux_sel && tx_mux_sel == ack_type) begin
         encodeOut = {c_local+1, parity, ack_type, block_type};
      end
      else if (mux_sel && tx_mux_sel == beacon_type) begin
         encodeOut = {c_local+1, parity, beacon_type, block_type};
      end
      else if (mux_sel && fromHostFifo.notEmpty) begin
         let host_data = fromHostFifo.first;
         debug_from_host <= host_data;
         encodeOut = {host_data, log_type, block_type};
         fromHostFifo.deq;
      end
      else begin
         encodeOut = v;
      end
      if(verbose) $display("%d: %d dtpTxOut=%h, c_local=%h, encodeOut=%h", cycle, id, v, c_local, encodeOut[11:10]);
      dtpTxOutFifo.enq(encodeOut);
   endrule

   // delay measurement
   rule delay_measurment(curr_state == INIT || curr_state == SENT);
      let init_timeout = fromInteger(valueOf(INIT_TIMEOUT));
      let init_type = fromInteger(valueOf(INIT_TYPE));
      let ack_type = fromInteger(valueOf(ACK_TYPE));
      dmFifo.deq;
      // Timeout driven output
      if (timeout_count_init > init_timeout) begin
         if (is_idle) begin
            timeout_count_init <= 0;
         end
         else begin
            timeout_count_init <= timeout_count_init + 1;
         end
         tx_mux_sel <= init_type;
         if(verbose) $display("%d: %d, init timed_out %d", cycle, id, timeout_count_init);
      end
      else if (init_rcvd) begin
         timeout_count_init <= timeout_count_init + 1;
         tx_mux_sel <= ack_type;
      end
      else begin
         timeout_count_init <= timeout_count_init + 1;
         tx_mux_sel <= 2'b00;
      end

      // compute delay
      if (ack_rcvd) begin
         let temp = outstandingInitRequest.first;
         delay <= (c_local - temp - 1) >> 1;
         if(verbose) $display("%d: %d update delay=%h, %h, %h", cycle, id, c_local, temp, (c_local-temp-1)>>1);
         outstandingInitRequest.deq;
      end
   endrule

   // Beacon
   rule beacon(curr_state == SYNC);
      dmFifo.deq;
      let sync_timeout = fromInteger(valueOf(SYNC_TIMEOUT));
      let beacon_type = fromInteger(valueOf(BEACON_TYPE));
      let ack_type = fromInteger(valueOf(ACK_TYPE));
      if (timeout_count_sync >= sync_timeout) begin
         if (is_idle) begin
            timeout_count_sync <= 0;
         end
         else begin
            timeout_count_sync <= timeout_count_sync + 1;
         end
         tx_mux_sel <= beacon_type;
      end
      else if (init_rcvd) begin
         tx_mux_sel <= ack_type;
         timeout_count_sync <= timeout_count_sync + 1;
      end
      else begin
         timeout_count_sync <= timeout_count_sync + 1;
         tx_mux_sel <= 2'b00;
      end

      if (ack_rcvd) begin
         let temp = outstandingInitRequest.first;
         delay <= (c_local - temp - 1) >> 1;
         if(verbose) $display("%d: %d update delay=%h, %h, %h", cycle, id, c_local, temp, (c_local-temp-1)>>1);
         outstandingInitRequest.deq;
      end
   endrule

   // DTP state machine
   rule state_init (curr_state == INIT);
      let init_type = fromInteger(valueOf(INIT_TYPE));
      cfFifo.deq;

      // update states
      if (tx_mux_sel == init_type && is_idle) begin
         curr_state <= SENT;
      end
      else if (init_rcvd) begin
         curr_state <= INIT;
      end
      else begin
         curr_state <= INIT;
      end
      //if(verbose) $display("%d: %d curr_state=%h", cycle, id, curr_state);
   endrule

   rule state_sent (curr_state == SENT);
      let init_type = fromInteger(valueOf(INIT_TYPE));
      cfFifo.deq;

      // update states
      if (init_rcvd) begin
         curr_state <= SENT;
      end
      else if (ack_rcvd) begin
         curr_state <= SYNC;
      end
      else if (tx_mux_sel == init_type) begin
         curr_state <= INIT;
      end
      else begin
         curr_state <= SENT;
      end
   endrule

   rule state_sync (curr_state == SYNC);
      cfFifo.deq;

      // update states
      if (init_rcvd) begin
         curr_state <= SYNC;
      end
      else begin
         curr_state <= SYNC;
      end
   endrule

   Probe#(Bit#(53)) debug_to_host <- mkProbe();
   // Parse received DTP frame
   // Remove DTP timestamp before passing frame to MAC.
   rule rx_stage1(tx_ready_wire && rx_ready_wire);
      let init_type   = fromInteger(valueOf(INIT_TYPE));
      let ack_type    = fromInteger(valueOf(ACK_TYPE));
      let beacon_type = fromInteger(valueOf(BEACON_TYPE));
      let log_type    = fromInteger(valueOf(LOG_TYPE));
      let v <- toGet(dtpRxInFifo).get();
      Bit#(1)  parity = ^v[65:13];
      Bit#(53) c_remote = v[65:13];
      Bit#(66) vo = v;
      Bool init_rcvd_next   = False;
      Bool ack_rcvd_next    = False;
      Bool beacon_rcvd_next = False;
      Bool log_rcvd_next    = False;
      vo[65:10] = 56'h0;

      if (v[9:2] == 8'h1e) begin
         if (v[11:10] == init_type) begin
            if (parity == v[12]) begin
               init_rcvd_next = True;
               //init_rcvd <= True;
               //ack_rcvd <= False;
               //beacon_rcvd <= False;
               //vo[65:10] = 56'h0;
               if(verbose) $display("%d: %d init_rcvd %h %h", cycle, id, c_remote, c_local);
            end
            else begin
               $display("parity mismatch: expected %h, found %h", parity, v[12]);
            end
         end
         else if (v[11:10] == ack_type) begin
            if (parity == v[12]) begin
               ack_rcvd_next = True;
               //init_rcvd <= False;
               //ack_rcvd <= True;
               //beacon_rcvd <= False;
               //vo[65:10] = 56'h0;
               if(verbose) $display("%d: %d ack_rcvd %h %h", cycle, id, c_remote, c_local);
            end
            else begin
               $display("parity mismatch: expected %h, found %h", parity, v[12]);
            end
         end
         else if (v[11:10] == beacon_type) begin
            if (parity == v[12]) begin
               beacon_rcvd_next = True;
               //init_rcvd <= False;
               //ack_rcvd <= False;
               //beacon_rcvd <= True;
               //vo[65:10] = 56'h0;
               localCompareRemoteFifo.enq(c_local + 1);
               remoteCompareLocalFifo.enq(c_remote + 1);
               if(verbose) $display("%d: %d beacon_rcvd %h %h", cycle, id, c_remote, c_local);
            end
            else begin
               $display("parity mismatch: expected %h, found %h", parity, v[12]);
            end
         end
         else if (v[12:10] == log_type) begin
            // send v[65:13] to logger.
            log_rcvd_next = True;
            //vo[65:10] = 56'h0;
            debug_to_host <= v[65:13];
            //FIXME: enable toHost.
            if (toHostFifo.notFull) begin
               toHostFifo.enq(v[65:13]);
            end
         end
//         else begin
//            init_rcvd <= False;
//            ack_rcvd <= False;
//            beacon_rcvd <= False;
//         end
         dtpEventFifo.enq(v[11:10]);
      end
      else begin
//         init_rcvd <= False;
//         ack_rcvd <= False;
//         beacon_rcvd <= False;
         dtpEventFifo.enq(2'b0);
      end
      //if(verbose) $display("%d: %d dtpRxIn=%h", cycle, id, v);
      //if(verbose) $display("%d: %d curr_state=%h", cycle, id, curr_state);
      init_rcvd   <= init_rcvd_next;
      ack_rcvd    <= ack_rcvd_next;
      beacon_rcvd <= beacon_rcvd_next;
      log_rcvd    <= log_rcvd_next;
      dtpRxOutFifo.enq(vo);
   endrule

   rule rx_stage2 (mode==0 || mode==1);
      let v_local <- toGet(localCompareRemoteFifo).get();
      let v_remote <- toGet(remoteCompareLocalFifo).get();
      if(verbose) $display("%d: %d, v_local=%h, v_remote=%h, delay=%h", cycle, id, v_local, v_remote, delay);
      if (v_local + 1 <= v_remote + delay) begin
         localLeRemoteFifo.enq(True);
         localGtRemoteFifo.enq(False);
      end
      else begin
         localLeRemoteFifo.enq(False);
         localGtRemoteFifo.enq(True);
      end
      localOutputFifo.enq(v_local + 1);
      remoteOutputFifo.enq(v_remote + 1);
   endrule

   rule compare_global_remote (mode==1);
      let global_delay = fromInteger(valueOf(GLOBAL_DELAY));
      let v_global <- toGet(globalCompareRemoteFifo).get();
      let v_remote <- toGet(remoteCompareGlobalFifo).get();
      if (v_global + global_delay <= v_remote + delay) begin
         globalLeRemoteFifo.enq(True);
         globalGtRemoteFifo.enq(False);
      end
      else begin
         globalLeRemoteFifo.enq(False);
         globalGtRemoteFifo.enq(True);
      end
      globalOutputFifo.enq(v_global);
   endrule

   rule compare_global_local (mode==1);
      let global_delay = fromInteger(valueOf(GLOBAL_DELAY));
      let v_global <- toGet(globalCompareLocalFifo).get();
      let v_local <- toGet(localCompareGlobalFifo).get();
      if (v_global + global_delay <= v_local + 1) begin
         globalLeLocalFifo.enq(True);
         globalGtLocalFifo.enq(False);
      end
      else begin
         globalLeLocalFifo.enq(False);
         globalGtLocalFifo.enq(True);
      end
   endrule

   rule rx_stage2_bypass;
      let v_event <- toGet(dtpEventFifo).get();
      dtpEventOutputFifo.enq(v_event);
   endrule

   rule rx_stage3_compute_c_local_next(mode==0);
      let vLocal <- toGet(localOutputFifo).get();
      let vRemote <- toGet(remoteOutputFifo).get();
      let useLocal <- toGet(localGtRemoteFifo).get();
      let _unused_ <- toGet(localLeRemoteFifo).get();
      if(verbose) $display("%d: %d, vLocal=%h", cycle, id, vLocal);
      if(verbose) $display("%d: %d, vRemote=%h", cycle, id, vRemote);
      if(verbose) $display("%d: %d, delay=%h", cycle, id, delay);
      if (useLocal) begin
         c_local_next <= vLocal + 1;
      end
      else begin
         c_local_next <= vRemote + delay + 1;
      end
   endrule

   rule output_switch (mode==1);
      let v_local <- toGet(localOutputFifo).get();
      let v_remote <- toGet(remoteOutputFifo).get();
      let v_global <- toGet(globalOutputFifo).get();
      let isGR <- toGet(globalGtRemoteFifo).get();
      let isGL <- toGet(globalGtLocalFifo).get();
      let isLR <- toGet(localGtRemoteFifo).get();
      let isLG <- toGet(globalLeLocalFifo).get();
      let isRG <- toGet(globalLeRemoteFifo).get();
      let isRL <- toGet(localLeRemoteFifo).get();
      let global_delay = fromInteger(valueOf(GLOBAL_DELAY));
      if (isGR && isGL) begin
         c_local_next <= v_global + global_delay;
      end
      else if (isLR && isLG) begin
         c_local_next <= v_local + 3;
      end
      else if (isRG && isRL) begin
         c_local_next <= v_remote + delay;
      end
   endrule

   rule rx_stage3;
      let v <- toGet(dtpEventOutputFifo).get();
      Bit#(2) beacon_type = fromInteger(valueOf(BEACON_TYPE));
      if (v == beacon_type) begin
         c_local <= c_local_next;
         if(verbose) $display("%d: %d c_local_next = %h", cycle, id, c_local_next);
      end
      else begin
         c_local <= c_local + 1;
      end
   endrule

   rule export_delay;
      delayFifo.enq(truncate(delay));
   endrule

   rule export_state;
      stateFifo.enq(zeroExtend(pack(curr_state)));
   endrule

   method Action tx_ready(Bool v);
      tx_ready_wire <= v;
   endmethod

   method Action rx_ready(Bool v);
      rx_ready_wire <= v;
   endmethod

   interface api = (interface DtpToPhyIfc;
      interface delayOut = toPipeOut(delayFifo);
      interface stateOut = toPipeOut(stateFifo);
      interface toHost   = toPipeOut(toHostFifo);
      interface fromHost = toPipeIn(fromHostFifo);
   endinterface);
   interface dtpRxIn = toPipeIn(dtpRxInFifo);
   interface dtpTxIn = toPipeIn(dtpTxInFifo);
   interface dtpRxOut = toPipeOut(dtpRxOutFifo);
   interface dtpTxOut = toPipeOut(dtpTxOutFifo);
endmodule
endpackage


Cleanup: remove unused AvalonBfm.bsv

Cleanup: remove unused AvalonBfm.bsv

// Copyright (c) 2015 Connectal Project.

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

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

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

interface AvalonBfm#(numeric type addrWidth, numeric type dataWidth);
endinterface

module mkAvalonBfm#(PhysMemMaster#(addrWidth, dataWidth) physmem)(AvalonBfm#(addrWidth, dataWidth));
   AvalonBfmWrapper#(addrWidth, dataWidth) bfm <- mkAvalonBfmWrapper();
   AvalonMMasterBits#(addrWidth, dataWidth) master <- mkAvalonDmaMaster(physmem);
   //mkConnection(master, bfm.slave);
endmodule


put hirschB and C here

put hirschB and C here

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

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

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

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

import StmtFSM::*;

module mkHirschA#(BRAMServer#(Bit#(strIndexWidth), 8) strA, BRAMServer#(Bit#(strIndexWidth), 8) strB, BRAMServer#(Bit#(lIndexWidth), 16) matL)(FSM)

    Reg#(Bit#(7)) aLenReg <- mkReg(0);
  Reg#(Bit#(7)) bLenReg <- mkReg(0);
  Reg#(Bit#(14)) rLenReg <- mkReg(0);
  Reg#(Bit#(7)) ii <- mkReg(0);
  Reg#(Bit#(7)) jj <- mkReg(0);
   Reg#(Char) aData <- mkReg(0);
   Reg#(Char) bData <- mkReg(0);
   Reg#(Bit#(16)) k0jm1 <- mkReg(0);
  Reg#(Bit#(16)) k1j <- mkReg(0);

  Stmt hirschB =
   seq
      /* initialize two rows of temporary storage */
      for (jj <= 0; jj < aLenReg; jj <= jj + 1)
	 seq
	    matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {0,jj}, datain: 0});
	    matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {1,jj}, datain: 0});
	 endseq
      /* Loop through string a */
      for (ii <= 1; ii <= aLenReg; ii <= ii + 1)
	 seq
	    /* Copy L[1] to L[0].  could pingpong instead, or unroll loop */
	    for (jj <= 0; jj <= bLenReg; jj <= jj + 1)
	       seq
		  matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {0,jj}, datain: 0});
		  action
		     let ta <- matL.response.get();
		     matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {1,jj}, datain: ta});
		  endaction
	       endseq
	    /* Loop through string B */
	    for (jj <= 0; jj <= bLenReg; jj <= jj + 1)
	       seq
		  /* Read a[i] and b[j] */
		  strA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: ii-1, datain: 0});
		  strB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: jj-1, datain: 0});
		  action
		     let ta <- strA.response.get();
		     let tb <- strB.response.get();
		     aData <= ta;
		     bData <= tb;
		  endaction
		  if (aData == bData)
		     seq
			matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {1,jj-1}, datain: 0});
			action
			   let ta <- matL.response.get();
			   matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {0,jj}, datain: ta + 1});
			endaction
		     endseq
		  else
		     seq
			/* read K[0][j] and K[1][j-1] */
			matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {1,jj}, datain: 0});
			action
			   let ta <- matL.response.get();
			   k0j <= ta;
			endaction
			matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {0,jj-1}, datain: 0});
			action
			   let ta <- matL.response.get();
			   k1jm1 <= ta
			endaction
			matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {0,jj}, datain: max(k0j,k1jm1)});
		     endseq
		  endseq
	 endseq
   endseq;

   Stmt hirschC =
   seq

   endseq;

   mkFSM(hirschB);
endmodule

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

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

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

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

import StmtFSM::*;

module mkHirschA#(BRAMServer#(Bit#(strIndexWidth), 8) strA, BRAMServer#(Bit#(strIndexWidth), 8) strB, BRAMServer#(Bit#(lIndexWidth), 16) matL)(FSM)

    Reg#(Bit#(7)) aLenReg <- mkReg(0);
  Reg#(Bit#(7)) bLenReg <- mkReg(0);
  Reg#(Bit#(14)) rLenReg <- mkReg(0);
  Reg#(Bit#(7)) ii <- mkReg(0);
  Reg#(Bit#(7)) jj <- mkReg(0);
   Reg#(Char) aData <- mkReg(0);
   Reg#(Char) bData <- mkReg(0);
   Reg#(Bit#(16)) lim1jm1 <- mkReg(0);
   Reg#(Bit#(16)) lim1j <- mkReg(0);
   Reg#(Bit#(16)) lijm1 <- mkReg(0);

   Stmt hirschA =
   seq
      for (ii<= 0; ii < aLenReg; ii <= ii + 1)
	 seq
	    matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {ii,0}, datain: 0});
	    endseq
      for (ii<= 0; ii < aLenReg; ii <= ii + 1)
	 seq
	    matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {0,ii}, datain: 0});
	 endseq
      for (ii<= 1; ii <= aLenReg; ii <= ii + 1)
	 for (jj<= 1; jj <= bLenReg; jj <= jj + 1)
	    seq
	       strA.request.put(BRAMRequest{write: False, responseOnWrite: False, address: ii-1, datain: 0});
	       strB.request.put(BRAMRequest{write: False, responseOnWrite: False, address: jj-1, datain: 0});
	       action
		  let ta <- strA.response.get();
		  let tb <- strB.response.get();
		  aData <= ta;
		  bData <= tb;
	       endaction
	       if (aData == bData)
		  seq
		     matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {ii-1,jj-1}, datain: 0});
		     action
			let temp <- matL.response.get();
			lim1jm1 <= temp;
		     endaction
		     matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {ii,jj}, datain: lim1jm1+1});

		  endseq
	       else
		  seq
		     matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {ii,jj-1}, datain: 0});
		     action
			let tlijm1 <- matL.response.get();
			lijm1 <= tlijm1;
		     endaction
		     matL.request.put(BRAMRequest{write: False, responseOnWrite: False, address: {ii-1,jj}, datain: 0});
		     action
			let tlim1j <- matL.response.get();
			lim1j <= tlim1j;
		     endaction
			matL.request.put(BRAMRequest{write: True, responseOnWrite: False, address: {ii,jj}, datain: max(lijm1,lim1j)});
		  endseq
	    endseq
      ff.enq(?);
   endseq;
   mkFSM(HirschA);

endmodule


dequeue and print

dequeue and print

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

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

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

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

import FIFOF::*;
import GetPutF::*;
import Dma::*;
import RingTypes::*;
import StmtFSM::*;

// The interface to the copyengine is a pair of fifos which supply and accept
// blocks of 8 64 bit words
// A Command:
//  word 0: COPY[63:56] TAG[31:0]
//  word 1: readMemHandle[63:32]
//  word 1: readAddress[23:0]
//  word 2  writeMemHandle[63:32]
//  word 2: writeAddress[23:0]
//  word 3: bytecount[15:0]
//  word 4-7 unused
// Status
//  word0-6 all 0
//  word7  TAG[31:0]

module mkCopyEngine#(DmaReadServer#(64) copy_read_chan, DmaWriteServer#(64) copy_write_chan) ( ServerF#(Bit#(64), Bit#(64)));
   FIFOF#(Bit#(64)) f_in  <- mkSizedFIFOF(16);    // to buffer incoming requests
   FIFOF#(Bit#(64)) f_out <- mkSizedFIFOF(16);    // to buffer outgoing responses
   Reg#(Bit#(16)) copyReadCount <- mkReg(0);
   Reg#(Bit#(16)) copyWriteCount <- mkReg(0);
   Reg#(Bit#(DmaAddrSize)) copyReadAddr <- mkReg(0);
   Reg#(Bit#(DmaAddrSize)) copyWriteAddr <- mkReg(0);
   Reg#(DmaPointer) copyReadHandle <- mkReg(0);
   Reg#(DmaPointer) copyWriteHandle <- mkReg(0);
   Reg#(Bit#(32)) copyTag <- mkReg(0);
   Reg#(Bool) copyBusy <- mkReg(False);
   Reg#(Bit#(4)) cmdCtr <- mkReg(0);
   Stmt copyStart =
   seq
      while(True)
	 seq
	    while (copyBusy) noAction;
	    for (cmdCtr <= 0; cmdCtr < 8; cmdCtr <= cmdCtr + 1)
	       action
		  $display("COPY %h %h", cmdCtr, f_in.first());
		  f_in.deq();
	       endaction

	    /*
	    action
	       copyTag <= f_in.first()[31:0];
	       f_in.deq();  // word 0
	    endaction
	    action
	       copyReadHandle <= f_in.first()[63:32];
	       copyReadAddr <= f_in.first()[23:0];
	       f_in.deq();  // word 1
	    endaction
	    action
	       copyWriteHandle <= f_in.first()[63:32];
	       copyWriteAddr <= f_in.first()[23:0];
	       f_in.deq();  // word 2
	    endaction
	    action
	       copyReadCount <= f_in.first()[15:0];
	       copyWriteCount <= f_in.first()[15:0];
	       f_in.deq();  // word 3
	    endaction
	       f_in.deq;  // discard words 4-7
	       f_in.deq;  // discard words 4-7
	       f_in.deq;  // discard words 4-7
	       f_in.deq;  // discard words 4-7
	    $display("copyStart from %h to %h count %h",
	       copyReadAddr, copyWriteAddr, copyReadCount);
	    copyBusy <= True;
	     */
	 endseq
   endseq;

    rule copyReadRule (copyBusy && (copyReadCount != 0));
       $display("copyRead %h, count %h", copyReadAddr, copyReadCount);
       copy_read_chan.readReq.put(DmaRequest{handle: copyReadHandle, address: copyReadAddr, burstLen: 1, tag: copyReadAddr[8:3]});
       copyReadAddr <= copyReadAddr + 8;
       copyReadCount <= copyReadCount - 8;
    endrule

    rule copyReadWriteRule (copyBusy);
       let data <- copy_read_chan.readData.get;
       $display("copyReadWrite addr %h", copyWriteAddr);
       copy_write_chan.writeReq.put(DmaRequest{handle: copyWriteHandle, address: copyWriteAddr, burstLen: 1, tag: copyWriteAddr[8:3]});
       copy_write_chan.writeData.put(DmaData{data: data.data, tag: copyWriteAddr[8:3]});
       copyWriteAddr <= copyWriteAddr + 8;
    endrule

   Stmt copyFinish =
   seq
      while(True)
	 seq
	    while (!copyBusy) noAction;
	    while (copyWriteCount > 0)
	       action
		  let v <- copy_write_chan.writeDone.get;
		  $display("copyWriteAck");
		  copyWriteCount <= copyWriteCount - 8;
	       endaction
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(extend(copyTag));
	    copyBusy <= False;
	 endseq
   endseq;

   mkAutoFSM(copyStart);
   mkAutoFSM(copyFinish);

   interface PutF request = toPutF(f_in);
   interface GetF response = toGetF (f_out);

endmodule: mkCopyEngine

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

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

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

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

import FIFOF::*;
import GetPutF::*;
import Dma::*;
import RingTypes::*;
import StmtFSM::*;

// The interface to the copyengine is a pair of fifos which supply and accept
// blocks of 8 64 bit words
// A Command:
//  word 0: COPY[63:56] TAG[31:0]
//  word 1: readMemHandle[63:32]
//  word 1: readAddress[23:0]
//  word 2  writeMemHandle[63:32]
//  word 2: writeAddress[23:0]
//  word 3: bytecount[15:0]
//  word 4-7 unused
// Status
//  word0-6 all 0
//  word7  TAG[31:0]

module mkCopyEngine#(DmaReadServer#(64) copy_read_chan, DmaWriteServer#(64) copy_write_chan) ( ServerF#(Bit#(64), Bit#(64)));
   FIFOF#(Bit#(64)) f_in  <- mkSizedFIFOF(16);    // to buffer incoming requests
   FIFOF#(Bit#(64)) f_out <- mkSizedFIFOF(16);    // to buffer outgoing responses
   Reg#(Bit#(16)) copyReadCount <- mkReg(0);
   Reg#(Bit#(16)) copyWriteCount <- mkReg(0);
   Reg#(Bit#(DmaAddrSize)) copyReadAddr <- mkReg(0);
   Reg#(Bit#(DmaAddrSize)) copyWriteAddr <- mkReg(0);
   Reg#(DmaPointer) copyReadHandle <- mkReg(0);
   Reg#(DmaPointer) copyWriteHandle <- mkReg(0);
   Reg#(Bit#(32)) copyTag <- mkReg(0);
   Reg#(Bool) copyBusy <- mkReg(False);
   Stmt copyStart =
   seq
      while(True)
	 seq
	    while (copyBusy) noAction;
	    action
	       copyTag <= f_in.first()[31:0];
	       f_in.deq();  // word 0
	    endaction
	    action
	       copyReadHandle <= f_in.first()[63:32];
	       copyReadAddr <= f_in.first()[23:0];
	       f_in.deq();  // word 1
	    endaction
	    action
	       copyWriteHandle <= f_in.first()[63:32];
	       copyWriteAddr <= f_in.first()[23:0];
	       f_in.deq();  // word 2
	    endaction
	    action
	       copyReadCount <= f_in.first()[15:0];
	       copyWriteCount <= f_in.first()[15:0];
	       f_in.deq();  // word 3
	    endaction
	       f_in.deq;  // discard words 4-7
	       f_in.deq;  // discard words 4-7
	       f_in.deq;  // discard words 4-7
	       f_in.deq;  // discard words 4-7
	    $display("copyStart from %h to %h count %h",
	       copyReadAddr, copyWriteAddr, copyReadCount);
	    copyBusy <= True;
	 endseq
   endseq;

    rule copyReadRule (copyBusy && (copyReadCount != 0));
       $display("copyRead %h, count %h", copyReadAddr, copyReadCount);
       copy_read_chan.readReq.put(DmaRequest{handle: copyReadHandle, address: copyReadAddr, burstLen: 1, tag: copyReadAddr[8:3]});
       copyReadAddr <= copyReadAddr + 8;
       copyReadCount <= copyReadCount - 8;
    endrule

    rule copyReadWriteRule (copyBusy);
       let data <- copy_read_chan.readData.get;
       $display("copyReadWrite addr %h", copyWriteAddr);
       copy_write_chan.writeReq.put(DmaRequest{handle: copyWriteHandle, address: copyWriteAddr, burstLen: 1, tag: copyWriteAddr[8:3]});
       copy_write_chan.writeData.put(DmaData{data: data.data, tag: copyWriteAddr[8:3]});
       copyWriteAddr <= copyWriteAddr + 8;
    endrule

   Stmt copyFinish =
   seq
      while(True)
	 seq
	    while (!copyBusy) noAction;
	    while (copyWriteCount > 0)
	       action
		  let v <- copy_write_chan.writeDone.get;
		  $display("copyWriteAck");
		  copyWriteCount <= copyWriteCount - 8;
	       endaction
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(0);
	    f_out.enq(extend(copyTag));
	    copyBusy <= False;
	 endseq
   endseq;

   mkAutoFSM(copyStart);
   mkAutoFSM(copyFinish);

   interface PutF request = toPutF(f_in);
   interface GetF response = toGetF (f_out);

endmodule: mkCopyEngine