refactor

refactor

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

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

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

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

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

(* always_ready, always_enabled *)
interface AxiREQ#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    Bit#(32)             ADDR;
    Bit#(2)              BURST;
    Bit#(4)              CACHE;
    Bit#(C_ID_WIDTH)     ID;
    Bit#(4)              LEN;
    Bit#(2)              LOCK;
    Bit#(3)              PROT;
    Bit#(4)              QOS;
    Bit#(3)              SIZE;
    Bit#(1)              VALID;
endinterface
interface AxiMOSI#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    AxiREQ               AR;
    AxiREQ               AW;
    Bit#(1)              BREADY;
    Bit#(1)              RREADY;
    Bit#(C_DATA_WIDTH)   WDATA;
    Bit#(C_ID_WIDTH)     WID;
    Bit#(1)              WLAST;
    Bit#(C_DATA_WIDTH/8) WSTRB;
    Bit#(1)              WVALID;
endinterface
interface AxiVALID#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    Bit#(C_ID_WIDTH)     ID;
    Bit#(2)              RESP;
    Bit#(1)              VALID;
endinterface
interface AxiMISO(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    Bit#(1)              ARREADY;
    Bit#(1)              AWREADY;
    AxiVALID#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH) B;
    AxiVALID#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH) R;
    Bit#(C_DATA_WIDTH)   RDATA;
    Bit#(1)              RLAST;
    Bit#(1)              WREADY;
endinterface
interface AxiMasterCommon#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    method Action ACLK(Bit#(1) v); // common
    method Bit#(1) ARESETN();      // common
    AxiMOSI#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    AxiMISO#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    method Action ARADDR(Bit#(32) v);
    method Action ARBURST(Bit#(2) v);
    method Action ARCACHE(Bit#(4) v);
    method Action ARID(Bit#(C_ID_WIDTH) v);
    method Action ARLEN(Bit#(4) v);
    method Action ARLOCK(Bit#(2) v);
    method Action ARPROT(Bit#(3) v);
    method Action ARQOS(Bit#(4) v);
    method Bit#(1) ARREADY();
    method Action ARSIZE(Bit#(3) v);
    method Action ARVALID(Bit#(1) v);
    method Action AWADDR(Bit#(32) v);
    method Action AWBURST(Bit#(2) v);
    method Action AWCACHE(Bit#(4) v);
    method Action AWID(Bit#(C_ID_WIDTH) v);
    method Action AWLEN(Bit#(4) v);
    method Action AWLOCK(Bit#(2) v);
    method Action AWPROT(Bit#(3) v);
    method Action AWQOS(Bit#(4) v);
    method Bit#(1) AWREADY();
    method Action AWSIZE(Bit#(3) v);
    method Action AWVALID(Bit#(1) v);
    method Bit#(C_ID_WIDTH) BID();
    method Action BREADY(Bit#(1) v);
    method Bit#(2) BRESP();
    method Bit#(1) BVALID();
    method Bit#(C_DATA_WIDTH) RDATA();
    method Bit#(C_ID_WIDTH) RID();
    method Bit#(1) RLAST();
    method Action RREADY(Bit#(1) v);
    method Bit#(2) RRESP();
    method Bit#(1) RVALID();
    method Action WDATA(Bit#(C_DATA_WIDTH) v);
    method Action WID(Bit#(C_ID_WIDTH) v);
    method Action WLAST(Bit#(1) v);
    method Bit#(1) WREADY();
    method Action WSTRB(Bit#(C_DATA_WIDTH/8) v);
    method Action WVALID(Bit#(1) v);
endinterface

interface AxiMasterHighSpeed#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    interface AxiCommon#(C_DATA_WIDTH, C_ID_WIDTH) axi;
    method Bit#(3) RACOUNT();
    method Bit#(8) RCOUNT();
    method Action RDISSUECAP1_EN(Bit#(1) v);
    method Bit#(6) WACOUNT();
    method Bit#(8) WCOUNT();
    method Action WRISSUECAP1_EN(Bit#(1) v);
endinterface

interface Ps7#(numeric type C_EMIO_GPIO_WIDTH);
    method Action CAN0_PHY_RX(Bit#(1) v);
    method Bit#(1) CAN0_PHY_TX();
    method Action CAN1_PHY_RX(Bit#(1) v);
    method Bit#(1) CAN1_PHY_TX();
    method Action Core0_nFIQ(Bit#(1) v);
    method Action Core0_nIRQ(Bit#(1) v);
    method Action Core1_nFIQ(Bit#(1) v);
    method Action Core1_nIRQ(Bit#(1) v);
    method Action DDR_ARB(Bit#(4) v);
    method Bit#(15) DDR_Addr();
    method Bit#(3) DDR_BankAddr();
    method Bit#(1) DDR_CAS_n();
    method Bit#(1) DDR_CKE();
    method Bit#(1) DDR_CS_n();
    method Bit#(1) DDR_Clk();
    method Bit#(1) DDR_Clk_n();
    method Bit#(C_DM_WIDTH) DDR_DM();
    method Bit#(C_DQ_WIDTH) DDR_DQ();
    method Bit#(C_DQS_WIDTH) DDR_DQS();
    method Bit#(C_DQS_WIDTH) DDR_DQS_n();
    method Bit#(1) DDR_DRSTB();
    method Bit#(1) DDR_ODT();
    method Bit#(1) DDR_RAS_n();
    method Bit#(1) DDR_VRN();
    method Bit#(1) DDR_VRP();
    method Bit#(1) DDR_WEB();
    method Action DMA0_ACLK(Bit#(1) v);
    method Action DMA0_DAREADY(Bit#(1) v);
    method Bit#(2) DMA0_DATYPE();
    method Bit#(1) DMA0_DAVALID();
    method Action DMA0_DRLAST(Bit#(1) v);
    method Bit#(1) DMA0_DRREADY();
    method Action DMA0_DRTYPE(Bit#(2) v);
    method Action DMA0_DRVALID(Bit#(1) v);
    method Bit#(1) DMA0_RSTN();
    method Action DMA1_ACLK(Bit#(1) v);
    method Action DMA1_DAREADY(Bit#(1) v);
    method Bit#(2) DMA1_DATYPE();
    method Bit#(1) DMA1_DAVALID();
    method Action DMA1_DRLAST(Bit#(1) v);
    method Bit#(1) DMA1_DRREADY();
    method Action DMA1_DRTYPE(Bit#(2) v);
    method Action DMA1_DRVALID(Bit#(1) v);
    method Bit#(1) DMA1_RSTN();
    method Action DMA2_ACLK(Bit#(1) v);
    method Action DMA2_DAREADY(Bit#(1) v);
    method Bit#(2) DMA2_DATYPE();
    method Bit#(1) DMA2_DAVALID();
    method Action DMA2_DRLAST(Bit#(1) v);
    method Bit#(1) DMA2_DRREADY();
    method Action DMA2_DRTYPE(Bit#(2) v);
    method Action DMA2_DRVALID(Bit#(1) v);
    method Bit#(1) DMA2_RSTN();
    method Action DMA3_ACLK(Bit#(1) v);
    method Action DMA3_DAREADY(Bit#(1) v);
    method Bit#(2) DMA3_DATYPE();
    method Bit#(1) DMA3_DAVALID();
    method Action DMA3_DRLAST(Bit#(1) v);
    method Bit#(1) DMA3_DRREADY();
    method Action DMA3_DRTYPE(Bit#(2) v);
    method Action DMA3_DRVALID(Bit#(1) v);
    method Bit#(1) DMA3_RSTN();
    method Action ENET0_EXT_INTIN(Bit#(1) v);
    method Action ENET0_GMII_COL(Bit#(1) v);
    method Action ENET0_GMII_CRS(Bit#(1) v);
    method Action ENET0_GMII_RXD(Bit#(8) v);
    method Action ENET0_GMII_RX_CLK(Bit#(1) v);
    method Action ENET0_GMII_RX_DV(Bit#(1) v);
    method Action ENET0_GMII_RX_ER(Bit#(1) v);
    method Bit#(8) ENET0_GMII_TXD();
    method Action ENET0_GMII_TX_CLK(Bit#(1) v);
    method Bit#(1) ENET0_GMII_TX_EN();
    method Bit#(1) ENET0_GMII_TX_ER();
    method Action ENET0_MDIO_I(Bit#(1) v);
    method Bit#(1) ENET0_MDIO_MDC();
    method Bit#(1) ENET0_MDIO_O();
    method Bit#(1) ENET0_MDIO_T();
    method Bit#(1) ENET0_PTP_DELAY_REQ_RX();
    method Bit#(1) ENET0_PTP_DELAY_REQ_TX();
    method Bit#(1) ENET0_PTP_PDELAY_REQ_RX();
    method Bit#(1) ENET0_PTP_PDELAY_REQ_TX();
    method Bit#(1) ENET0_PTP_PDELAY_RESP_RX();
    method Bit#(1) ENET0_PTP_PDELAY_RESP_TX();
    method Bit#(1) ENET0_PTP_SYNC_FRAME_RX();
    method Bit#(1) ENET0_PTP_SYNC_FRAME_TX();
    method Bit#(1) ENET0_SOF_RX();
    method Bit#(1) ENET0_SOF_TX();
    method Action ENET1_EXT_INTIN(Bit#(1) v);
    method Action ENET1_GMII_COL(Bit#(1) v);
    method Action ENET1_GMII_CRS(Bit#(1) v);
    method Action ENET1_GMII_RXD(Bit#(8) v);
    method Action ENET1_GMII_RX_CLK(Bit#(1) v);
    method Action ENET1_GMII_RX_DV(Bit#(1) v);
    method Action ENET1_GMII_RX_ER(Bit#(1) v);
    method Bit#(8) ENET1_GMII_TXD();
    method Action ENET1_GMII_TX_CLK(Bit#(1) v);
    method Bit#(1) ENET1_GMII_TX_EN();
    method Bit#(1) ENET1_GMII_TX_ER();
    method Action ENET1_MDIO_I(Bit#(1) v);
    method Bit#(1) ENET1_MDIO_MDC();
    method Bit#(1) ENET1_MDIO_O();
    method Bit#(1) ENET1_MDIO_T();
    method Bit#(1) ENET1_PTP_DELAY_REQ_RX();
    method Bit#(1) ENET1_PTP_DELAY_REQ_TX();
    method Bit#(1) ENET1_PTP_PDELAY_REQ_RX();
    method Bit#(1) ENET1_PTP_PDELAY_REQ_TX();
    method Bit#(1) ENET1_PTP_PDELAY_RESP_RX();
    method Bit#(1) ENET1_PTP_PDELAY_RESP_TX();
    method Bit#(1) ENET1_PTP_SYNC_FRAME_RX();
    method Bit#(1) ENET1_PTP_SYNC_FRAME_TX();
    method Bit#(1) ENET1_SOF_RX();
    method Bit#(1) ENET1_SOF_TX();
    method Action EVENT_EVENTI(Bit#(1) v);
    method Bit#(1) EVENT_EVENTO();
    method Bit#(2) EVENT_STANDBYWFE();
    method Bit#(2) EVENT_STANDBYWFI();
    method Bit#(1) FCLK_CLK0();
    method Bit#(1) FCLK_CLK1();
    method Bit#(1) FCLK_CLK2();
    method Bit#(1) FCLK_CLK3();
    method Action FCLK_CLKTRIG0_N(Bit#(1) v);
    method Action FCLK_CLKTRIG1_N(Bit#(1) v);
    method Action FCLK_CLKTRIG2_N(Bit#(1) v);
    method Action FCLK_CLKTRIG3_N(Bit#(1) v);
    method Bit#(1) FCLK_RESET0_N();
    method Bit#(1) FCLK_RESET1_N();
    method Bit#(1) FCLK_RESET2_N();
    method Bit#(1) FCLK_RESET3_N();
    method Action FPGA_IDLE_N(Bit#(1) v);
    method Action FTMD_TRACEIN_ATID(Bit#(4) v);
    method Action FTMD_TRACEIN_CLK(Bit#(1) v);
    method Action FTMD_TRACEIN_DATA(Bit#(32) v);
    method Action FTMD_TRACEIN_VALID(Bit#(1) v);
    method Action FTMT_F2P_DEBUG(Bit#(32) v);
    method Action FTMT_F2P_TRIG(Bit#(4) v);
    method Bit#(4) FTMT_F2P_TRIGACK();
    method Bit#(32) FTMT_P2F_DEBUG();
    method Bit#(4) FTMT_P2F_TRIG();
    method Action FTMT_P2F_TRIGACK(Bit#(4) v);
    method Action GPIO_I(Bit#(C_EMIO_GPIO_WIDTH) v);
    method Bit#(C_EMIO_GPIO_WIDTH) GPIO_O();
    method Bit#(C_EMIO_GPIO_WIDTH) GPIO_T();
    method Action I2C0_SCL_I(Bit#(1) v);
    method Bit#(1) I2C0_SCL_O();
    method Bit#(1) I2C0_SCL_T();
    method Action I2C0_SDA_I(Bit#(1) v);
    method Bit#(1) I2C0_SDA_O();
    method Bit#(1) I2C0_SDA_T();
    method Action I2C1_SCL_I(Bit#(1) v);
    method Bit#(1) I2C1_SCL_O();
    method Bit#(1) I2C1_SCL_T();
    method Action I2C1_SDA_I(Bit#(1) v);
    method Bit#(1) I2C1_SDA_O();
    method Bit#(1) I2C1_SDA_T();
    method Action IRQ_F2P(Bit#(16) v);
    method Bit#(1) IRQ_P2F_CAN0();
    method Bit#(1) IRQ_P2F_CAN1();
    method Bit#(1) IRQ_P2F_CTI();
    method Bit#(1) IRQ_P2F_DMAC0();
    method Bit#(1) IRQ_P2F_DMAC1();
    method Bit#(1) IRQ_P2F_DMAC2();
    method Bit#(1) IRQ_P2F_DMAC3();
    method Bit#(1) IRQ_P2F_DMAC4();
    method Bit#(1) IRQ_P2F_DMAC5();
    method Bit#(1) IRQ_P2F_DMAC6();
    method Bit#(1) IRQ_P2F_DMAC7();
    method Bit#(1) IRQ_P2F_DMAC_ABORT();
    method Bit#(1) IRQ_P2F_ENET0();
    method Bit#(1) IRQ_P2F_ENET1();
    method Bit#(1) IRQ_P2F_ENET_WAKE0();
    method Bit#(1) IRQ_P2F_ENET_WAKE1();
    method Bit#(1) IRQ_P2F_GPIO();
    method Bit#(1) IRQ_P2F_I2C0();
    method Bit#(1) IRQ_P2F_I2C1();
    method Bit#(1) IRQ_P2F_QSPI();
    method Bit#(1) IRQ_P2F_SDIO0();
    method Bit#(1) IRQ_P2F_SDIO1();
    method Bit#(1) IRQ_P2F_SMC();
    method Bit#(1) IRQ_P2F_SPI0();
    method Bit#(1) IRQ_P2F_SPI1();
    method Bit#(1) IRQ_P2F_UART0();
    method Bit#(1) IRQ_P2F_UART1();
    method Bit#(1) IRQ_P2F_USB0();
    method Bit#(1) IRQ_P2F_USB1();
    method Bit#(C_MIO_PRIMITIVE) MIO();
    interface AxiSlaveCommon#(1) s_axi_acp;
>     method Action ARUSER(Bit#(5) v);
>     method Action AWUSER(Bit#(5) v);
    interface AxiSlaveCommon#(1) s_axi_gp0;
    interface AxiSlaveCommon#(1) s_axi_gp1;
    interface AxiSlaveHighSpeed#(1) s_axi_hp0;
    interface AxiSlaveHighSpeed#(1) s_axi_hp1;
    interface AxiSlaveHighSpeed#(1) s_axi_hp2;
    interface AxiSlaveHighSpeed#(1) s_axi_hp3;
    interface AxiMasterCommon#(1) m_axi_gp0;
    interface AxiMasterCommon#(1) m_axi_gp1;
    interface AxiMasterHighSpeed#(1) m_axi_hp0;
    interface AxiMasterHighSpeed#(1) m_axi_hp1;
    interface AxiMasterHighSpeed#(1) m_axi_hp2;
    interface AxiMasterHighSpeed#(1) m_axi_hp3;
    method Action PJTAG_TCK(Bit#(1) v);
    method Action PJTAG_TD_I(Bit#(1) v);
    method Bit#(1) PJTAG_TD_O();
    method Bit#(1) PJTAG_TD_T();
    method Action PJTAG_TMS(Bit#(1) v);
    method Action PS_CLK(Bit#(1) v);
    method Action PS_PORB(Bit#(1) v);
    method Action PS_SRSTB(Bit#(1) v);
    method Bit#(1) SDIO0_BUSPOW();
    method Bit#(3) SDIO0_BUSVOLT();
    method Action SDIO0_CDN(Bit#(1) v);
    method Bit#(1) SDIO0_CLK();
    method Action SDIO0_CLK_FB(Bit#(1) v);
    method Action SDIO0_CMD_I(Bit#(1) v);
    method Bit#(1) SDIO0_CMD_O();
    method Bit#(1) SDIO0_CMD_T();
    method Action SDIO0_DATA_I(Bit#(4) v);
    method Bit#(4) SDIO0_DATA_O();
    method Bit#(4) SDIO0_DATA_T();
    method Bit#(1) SDIO0_LED();
    method Action SDIO0_WP(Bit#(1) v);
    method Bit#(1) SDIO1_BUSPOW();
    method Bit#(3) SDIO1_BUSVOLT();
    method Action SDIO1_CDN(Bit#(1) v);
    method Bit#(1) SDIO1_CLK();
    method Action SDIO1_CLK_FB(Bit#(1) v);
    method Action SDIO1_CMD_I(Bit#(1) v);
    method Bit#(1) SDIO1_CMD_O();
    method Bit#(1) SDIO1_CMD_T();
    method Action SDIO1_DATA_I(Bit#(4) v);
    method Bit#(4) SDIO1_DATA_O();
    method Bit#(4) SDIO1_DATA_T();
    method Bit#(1) SDIO1_LED();
    method Action SDIO1_WP(Bit#(1) v);
    method Action SPI0_MISO_I(Bit#(1) v);
    method Bit#(1) SPI0_MISO_O();
    method Bit#(1) SPI0_MISO_T();
    method Action SPI0_MOSI_I(Bit#(1) v);
    method Bit#(1) SPI0_MOSI_O();
    method Bit#(1) SPI0_MOSI_T();
    method Action SPI0_SCLK_I(Bit#(1) v);
    method Bit#(1) SPI0_SCLK_O();
    method Bit#(1) SPI0_SCLK_T();
    method Bit#(1) SPI0_SS1_O();
    method Bit#(1) SPI0_SS2_O();
    method Action SPI0_SS_I(Bit#(1) v);
    method Bit#(1) SPI0_SS_O();
    method Bit#(1) SPI0_SS_T();
    method Action SPI1_MISO_I(Bit#(1) v);
    method Bit#(1) SPI1_MISO_O();
    method Bit#(1) SPI1_MISO_T();
    method Action SPI1_MOSI_I(Bit#(1) v);
    method Bit#(1) SPI1_MOSI_O();
    method Bit#(1) SPI1_MOSI_T();
    method Action SPI1_SCLK_I(Bit#(1) v);
    method Bit#(1) SPI1_SCLK_O();
    method Bit#(1) SPI1_SCLK_T();
    method Bit#(1) SPI1_SS1_O();
    method Bit#(1) SPI1_SS2_O();
    method Action SPI1_SS_I(Bit#(1) v);
    method Bit#(1) SPI1_SS_O();
    method Bit#(1) SPI1_SS_T();
    method Action SRAM_INTIN(Bit#(1) v);
    method Action TRACE_CLK(Bit#(1) v);
    method Bit#(1) TRACE_CTL();
    method Bit#(32) TRACE_DATA();
    method Action TTC0_CLK0_IN(Bit#(1) v);
    method Action TTC0_CLK1_IN(Bit#(1) v);
    method Action TTC0_CLK2_IN(Bit#(1) v);
    method Bit#(1) TTC0_WAVE0_OUT();
    method Bit#(1) TTC0_WAVE1_OUT();
    method Bit#(1) TTC0_WAVE2_OUT();
    method Action TTC1_CLK0_IN(Bit#(1) v);
    method Action TTC1_CLK1_IN(Bit#(1) v);
    method Action TTC1_CLK2_IN(Bit#(1) v);
    method Bit#(1) TTC1_WAVE0_OUT();
    method Bit#(1) TTC1_WAVE1_OUT();
    method Bit#(1) TTC1_WAVE2_OUT();
    method Action UART0_CTSN(Bit#(1) v);
    method Action UART0_DCDN(Bit#(1) v);
    method Action UART0_DSRN(Bit#(1) v);
    method Bit#(1) UART0_DTRN();
    method Action UART0_RIN(Bit#(1) v);
    method Bit#(1) UART0_RTSN();
    method Action UART0_RX(Bit#(1) v);
    method Bit#(1) UART0_TX();
    method Action UART1_CTSN(Bit#(1) v);
    method Action UART1_DCDN(Bit#(1) v);
    method Action UART1_DSRN(Bit#(1) v);
    method Bit#(1) UART1_DTRN();
    method Action UART1_RIN(Bit#(1) v);
    method Bit#(1) UART1_RTSN();
    method Action UART1_RX(Bit#(1) v);
    method Bit#(1) UART1_TX();
    method Bit#(2) USB0_PORT_INDCTL();
    method Action USB0_VBUS_PWRFAULT(Bit#(1) v);
    method Bit#(1) USB0_VBUS_PWRSELECT();
    method Bit#(2) USB1_PORT_INDCTL();
    method Action USB1_VBUS_PWRFAULT(Bit#(1) v);
    method Bit#(1) USB1_VBUS_PWRSELECT();
    method Action WDT_CLK_IN(Bit#(1) v);
    method Bit#(1) WDT_RST_OUT();
    method Action S_AXI_HP3_ACLK(Bit#(1) v);
    method Action TRACE_CLK(Bit#(1) v);
    method Bit#(1) TRACE_CTL();
    method Bit#(32) TRACE_DATA();
    method Action TTC0_CLK0_IN(Bit#(1) v);
    method Action TTC0_CLK1_IN(Bit#(1) v);
    method Action TTC0_CLK2_IN(Bit#(1) v);
    method Bit#(1) TTC0_WAVE0_OUT();
    method Bit#(1) TTC0_WAVE1_OUT();
    method Bit#(1) TTC0_WAVE2_OUT();
    method Action TTC1_CLK0_IN(Bit#(1) v);
    method Action TTC1_CLK1_IN(Bit#(1) v);
    method Action TTC1_CLK2_IN(Bit#(1) v);
    method Bit#(1) TTC1_WAVE0_OUT();
    method Bit#(1) TTC1_WAVE1_OUT();
    method Bit#(1) TTC1_WAVE2_OUT();
    method Action UART0_CTSN(Bit#(1) v);
    method Action UART0_DCDN(Bit#(1) v);
    method Action UART0_DSRN(Bit#(1) v);
    method Bit#(1) UART0_DTRN();
    method Action UART0_RIN(Bit#(1) v);
    method Bit#(1) UART0_RTSN();
    method Action UART0_RX(Bit#(1) v);
    method Bit#(1) UART0_TX();
    method Action UART1_CTSN(Bit#(1) v);
    method Action UART1_DCDN(Bit#(1) v);
    method Action UART1_DSRN(Bit#(1) v);
    method Bit#(1) UART1_DTRN();
    method Action UART1_RIN(Bit#(1) v);
    method Bit#(1) UART1_RTSN();
    method Action UART1_RX(Bit#(1) v);
    method Bit#(1) UART1_TX();
    method Bit#(2) USB0_PORT_INDCTL();
    method Action USB0_VBUS_PWRFAULT(Bit#(1) v);
    method Bit#(1) USB0_VBUS_PWRSELECT();
    method Bit#(2) USB1_PORT_INDCTL();
    method Action USB1_VBUS_PWRFAULT(Bit#(1) v);
    method Bit#(1) USB1_VBUS_PWRSELECT();
    method Action WDT_CLK_IN(Bit#(1) v);
    method Bit#(1) WDT_RST_OUT();

   schedule (datain, idatain, inc, ce) CF (datain, idatain, inc, ce);
endmodule

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

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

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

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

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

(* always_ready, always_enabled *)
interface AxiMasterCommon#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    method Action ACLK(Bit#(1) v);
    method Action ARADDR(Bit#(32) v);
    method Action ARBURST(Bit#(2) v);
    method Action ARCACHE(Bit#(4) v);
    method Bit#(1) ARESETN();
    method Action ARID(Bit#(C_ID_WIDTH) v);
    method Action ARLEN(Bit#(4) v);
    method Action ARLOCK(Bit#(2) v);
    method Action ARPROT(Bit#(3) v);
    method Action ARQOS(Bit#(4) v);
    method Bit#(1) ARREADY();
    method Action ARSIZE(Bit#(3) v);
    method Action ARVALID(Bit#(1) v);
    method Action AWADDR(Bit#(32) v);
    method Action AWBURST(Bit#(2) v);
    method Action AWCACHE(Bit#(4) v);
    method Action AWID(Bit#(C_ID_WIDTH) v);
    method Action AWLEN(Bit#(4) v);
    method Action AWLOCK(Bit#(2) v);
    method Action AWPROT(Bit#(3) v);
    method Action AWQOS(Bit#(4) v);
    method Bit#(1) AWREADY();
    method Action AWSIZE(Bit#(3) v);
    method Action AWVALID(Bit#(1) v);
    method Bit#(C_ID_WIDTH) BID();
    method Action BREADY(Bit#(1) v);
    method Bit#(2) BRESP();
    method Bit#(1) BVALID();
    method Bit#(C_DATA_WIDTH) RDATA();
    method Bit#(C_ID_WIDTH) RID();
    method Bit#(1) RLAST();
    method Action RREADY(Bit#(1) v);
    method Bit#(2) RRESP();
    method Bit#(1) RVALID();
    method Action WDATA(Bit#(C_DATA_WIDTH) v);
    method Action WID(Bit#(C_ID_WIDTH) v);
    method Action WLAST(Bit#(1) v);
    method Bit#(1) WREADY();
    method Action WSTRB(Bit#(C_DATA_WIDTH/8) v);
    method Action WVALID(Bit#(1) v);
endinterface

interface AxiMasterHighSpeed#(numeric type C_DATA_WIDTH, numeric type C_ID_WIDTH);
    interface AxiCommon#(C_DATA_WIDTH, C_ID_WIDTH) axi;
    method Bit#(3) RACOUNT();
    method Bit#(8) RCOUNT();
    method Action RDISSUECAP1_EN(Bit#(1) v);
    method Bit#(6) WACOUNT();
    method Bit#(8) WCOUNT();
    method Action WRISSUECAP1_EN(Bit#(1) v);
endinterface

interface Ps7#(numeric type C_EMIO_GPIO_WIDTH);
    method Action CAN0_PHY_RX(Bit#(1) v);
    method Bit#(1) CAN0_PHY_TX();
    method Action CAN1_PHY_RX(Bit#(1) v);
    method Bit#(1) CAN1_PHY_TX();
    method Action Core0_nFIQ(Bit#(1) v);
    method Action Core0_nIRQ(Bit#(1) v);
    method Action Core1_nFIQ(Bit#(1) v);
    method Action Core1_nIRQ(Bit#(1) v);
    method Action DDR_ARB(Bit#(4) v);
    method Bit#(15) DDR_Addr();
    method Bit#(3) DDR_BankAddr();
    method Bit#(1) DDR_CAS_n();
    method Bit#(1) DDR_CKE();
    method Bit#(1) DDR_CS_n();
    method Bit#(1) DDR_Clk();
    method Bit#(1) DDR_Clk_n();
    method Bit#(C_DM_WIDTH) DDR_DM();
    method Bit#(C_DQ_WIDTH) DDR_DQ();
    method Bit#(C_DQS_WIDTH) DDR_DQS();
    method Bit#(C_DQS_WIDTH) DDR_DQS_n();
    method Bit#(1) DDR_DRSTB();
    method Bit#(1) DDR_ODT();
    method Bit#(1) DDR_RAS_n();
    method Bit#(1) DDR_VRN();
    method Bit#(1) DDR_VRP();
    method Bit#(1) DDR_WEB();
    method Action DMA0_ACLK(Bit#(1) v);
    method Action DMA0_DAREADY(Bit#(1) v);
    method Bit#(2) DMA0_DATYPE();
    method Bit#(1) DMA0_DAVALID();
    method Action DMA0_DRLAST(Bit#(1) v);
    method Bit#(1) DMA0_DRREADY();
    method Action DMA0_DRTYPE(Bit#(2) v);
    method Action DMA0_DRVALID(Bit#(1) v);
    method Bit#(1) DMA0_RSTN();
    method Action DMA1_ACLK(Bit#(1) v);
    method Action DMA1_DAREADY(Bit#(1) v);
    method Bit#(2) DMA1_DATYPE();
    method Bit#(1) DMA1_DAVALID();
    method Action DMA1_DRLAST(Bit#(1) v);
    method Bit#(1) DMA1_DRREADY();
    method Action DMA1_DRTYPE(Bit#(2) v);
    method Action DMA1_DRVALID(Bit#(1) v);
    method Bit#(1) DMA1_RSTN();
    method Action DMA2_ACLK(Bit#(1) v);
    method Action DMA2_DAREADY(Bit#(1) v);
    method Bit#(2) DMA2_DATYPE();
    method Bit#(1) DMA2_DAVALID();
    method Action DMA2_DRLAST(Bit#(1) v);
    method Bit#(1) DMA2_DRREADY();
    method Action DMA2_DRTYPE(Bit#(2) v);
    method Action DMA2_DRVALID(Bit#(1) v);
    method Bit#(1) DMA2_RSTN();
    method Action DMA3_ACLK(Bit#(1) v);
    method Action DMA3_DAREADY(Bit#(1) v);
    method Bit#(2) DMA3_DATYPE();
    method Bit#(1) DMA3_DAVALID();
    method Action DMA3_DRLAST(Bit#(1) v);
    method Bit#(1) DMA3_DRREADY();
    method Action DMA3_DRTYPE(Bit#(2) v);
    method Action DMA3_DRVALID(Bit#(1) v);
    method Bit#(1) DMA3_RSTN();
    method Action ENET0_EXT_INTIN(Bit#(1) v);
    method Action ENET0_GMII_COL(Bit#(1) v);
    method Action ENET0_GMII_CRS(Bit#(1) v);
    method Action ENET0_GMII_RXD(Bit#(8) v);
    method Action ENET0_GMII_RX_CLK(Bit#(1) v);
    method Action ENET0_GMII_RX_DV(Bit#(1) v);
    method Action ENET0_GMII_RX_ER(Bit#(1) v);
    method Bit#(8) ENET0_GMII_TXD();
    method Action ENET0_GMII_TX_CLK(Bit#(1) v);
    method Bit#(1) ENET0_GMII_TX_EN();
    method Bit#(1) ENET0_GMII_TX_ER();
    method Action ENET0_MDIO_I(Bit#(1) v);
    method Bit#(1) ENET0_MDIO_MDC();
    method Bit#(1) ENET0_MDIO_O();
    method Bit#(1) ENET0_MDIO_T();
    method Bit#(1) ENET0_PTP_DELAY_REQ_RX();
    method Bit#(1) ENET0_PTP_DELAY_REQ_TX();
    method Bit#(1) ENET0_PTP_PDELAY_REQ_RX();
    method Bit#(1) ENET0_PTP_PDELAY_REQ_TX();
    method Bit#(1) ENET0_PTP_PDELAY_RESP_RX();
    method Bit#(1) ENET0_PTP_PDELAY_RESP_TX();
    method Bit#(1) ENET0_PTP_SYNC_FRAME_RX();
    method Bit#(1) ENET0_PTP_SYNC_FRAME_TX();
    method Bit#(1) ENET0_SOF_RX();
    method Bit#(1) ENET0_SOF_TX();
    method Action ENET1_EXT_INTIN(Bit#(1) v);
    method Action ENET1_GMII_COL(Bit#(1) v);
    method Action ENET1_GMII_CRS(Bit#(1) v);
    method Action ENET1_GMII_RXD(Bit#(8) v);
    method Action ENET1_GMII_RX_CLK(Bit#(1) v);
    method Action ENET1_GMII_RX_DV(Bit#(1) v);
    method Action ENET1_GMII_RX_ER(Bit#(1) v);
    method Bit#(8) ENET1_GMII_TXD();
    method Action ENET1_GMII_TX_CLK(Bit#(1) v);
    method Bit#(1) ENET1_GMII_TX_EN();
    method Bit#(1) ENET1_GMII_TX_ER();
    method Action ENET1_MDIO_I(Bit#(1) v);
    method Bit#(1) ENET1_MDIO_MDC();
    method Bit#(1) ENET1_MDIO_O();
    method Bit#(1) ENET1_MDIO_T();
    method Bit#(1) ENET1_PTP_DELAY_REQ_RX();
    method Bit#(1) ENET1_PTP_DELAY_REQ_TX();
    method Bit#(1) ENET1_PTP_PDELAY_REQ_RX();
    method Bit#(1) ENET1_PTP_PDELAY_REQ_TX();
    method Bit#(1) ENET1_PTP_PDELAY_RESP_RX();
    method Bit#(1) ENET1_PTP_PDELAY_RESP_TX();
    method Bit#(1) ENET1_PTP_SYNC_FRAME_RX();
    method Bit#(1) ENET1_PTP_SYNC_FRAME_TX();
    method Bit#(1) ENET1_SOF_RX();
    method Bit#(1) ENET1_SOF_TX();
    method Action EVENT_EVENTI(Bit#(1) v);
    method Bit#(1) EVENT_EVENTO();
    method Bit#(2) EVENT_STANDBYWFE();
    method Bit#(2) EVENT_STANDBYWFI();
    method Bit#(1) FCLK_CLK0();
    method Bit#(1) FCLK_CLK1();
    method Bit#(1) FCLK_CLK2();
    method Bit#(1) FCLK_CLK3();
    method Action FCLK_CLKTRIG0_N(Bit#(1) v);
    method Action FCLK_CLKTRIG1_N(Bit#(1) v);
    method Action FCLK_CLKTRIG2_N(Bit#(1) v);
    method Action FCLK_CLKTRIG3_N(Bit#(1) v);
    method Bit#(1) FCLK_RESET0_N();
    method Bit#(1) FCLK_RESET1_N();
    method Bit#(1) FCLK_RESET2_N();
    method Bit#(1) FCLK_RESET3_N();
    method Action FPGA_IDLE_N(Bit#(1) v);
    method Action FTMD_TRACEIN_ATID(Bit#(4) v);
    method Action FTMD_TRACEIN_CLK(Bit#(1) v);
    method Action FTMD_TRACEIN_DATA(Bit#(32) v);
    method Action FTMD_TRACEIN_VALID(Bit#(1) v);
    method Action FTMT_F2P_DEBUG(Bit#(32) v);
    method Action FTMT_F2P_TRIG(Bit#(4) v);
    method Bit#(4) FTMT_F2P_TRIGACK();
    method Bit#(32) FTMT_P2F_DEBUG();
    method Bit#(4) FTMT_P2F_TRIG();
    method Action FTMT_P2F_TRIGACK(Bit#(4) v);
    method Action GPIO_I(Bit#(C_EMIO_GPIO_WIDTH) v);
    method Bit#(C_EMIO_GPIO_WIDTH) GPIO_O();
    method Bit#(C_EMIO_GPIO_WIDTH) GPIO_T();
    method Action I2C0_SCL_I(Bit#(1) v);
    method Bit#(1) I2C0_SCL_O();
    method Bit#(1) I2C0_SCL_T();
    method Action I2C0_SDA_I(Bit#(1) v);
    method Bit#(1) I2C0_SDA_O();
    method Bit#(1) I2C0_SDA_T();
    method Action I2C1_SCL_I(Bit#(1) v);
    method Bit#(1) I2C1_SCL_O();
    method Bit#(1) I2C1_SCL_T();
    method Action I2C1_SDA_I(Bit#(1) v);
    method Bit#(1) I2C1_SDA_O();
    method Bit#(1) I2C1_SDA_T();
    method Action IRQ_F2P(Bit#(16) v);
    method Bit#(1) IRQ_P2F_CAN0();
    method Bit#(1) IRQ_P2F_CAN1();
    method Bit#(1) IRQ_P2F_CTI();
    method Bit#(1) IRQ_P2F_DMAC0();
    method Bit#(1) IRQ_P2F_DMAC1();
    method Bit#(1) IRQ_P2F_DMAC2();
    method Bit#(1) IRQ_P2F_DMAC3();
    method Bit#(1) IRQ_P2F_DMAC4();
    method Bit#(1) IRQ_P2F_DMAC5();
    method Bit#(1) IRQ_P2F_DMAC6();
    method Bit#(1) IRQ_P2F_DMAC7();
    method Bit#(1) IRQ_P2F_DMAC_ABORT();
    method Bit#(1) IRQ_P2F_ENET0();
    method Bit#(1) IRQ_P2F_ENET1();
    method Bit#(1) IRQ_P2F_ENET_WAKE0();
    method Bit#(1) IRQ_P2F_ENET_WAKE1();
    method Bit#(1) IRQ_P2F_GPIO();
    method Bit#(1) IRQ_P2F_I2C0();
    method Bit#(1) IRQ_P2F_I2C1();
    method Bit#(1) IRQ_P2F_QSPI();
    method Bit#(1) IRQ_P2F_SDIO0();
    method Bit#(1) IRQ_P2F_SDIO1();
    method Bit#(1) IRQ_P2F_SMC();
    method Bit#(1) IRQ_P2F_SPI0();
    method Bit#(1) IRQ_P2F_SPI1();
    method Bit#(1) IRQ_P2F_UART0();
    method Bit#(1) IRQ_P2F_UART1();
    method Bit#(1) IRQ_P2F_USB0();
    method Bit#(1) IRQ_P2F_USB1();
    method Bit#(C_MIO_PRIMITIVE) MIO();
    interface AxiSlaveCommon#(1) s_axi_acp;
>     method Action ARUSER(Bit#(5) v);
>     method Action AWUSER(Bit#(5) v);
    interface AxiSlaveCommon#(1) s_axi_gp0;
    interface AxiSlaveCommon#(1) s_axi_gp1;
    interface AxiSlaveHighSpeed#(1) s_axi_hp0;
    interface AxiSlaveHighSpeed#(1) s_axi_hp1;
    interface AxiSlaveHighSpeed#(1) s_axi_hp2;
    interface AxiSlaveHighSpeed#(1) s_axi_hp3;
    interface AxiMasterCommon#(1) m_axi_gp0;
    interface AxiMasterCommon#(1) m_axi_gp1;
    interface AxiMasterHighSpeed#(1) m_axi_hp0;
    interface AxiMasterHighSpeed#(1) m_axi_hp1;
    interface AxiMasterHighSpeed#(1) m_axi_hp2;
    interface AxiMasterHighSpeed#(1) m_axi_hp3;
    method Action PJTAG_TCK(Bit#(1) v);
    method Action PJTAG_TD_I(Bit#(1) v);
    method Bit#(1) PJTAG_TD_O();
    method Bit#(1) PJTAG_TD_T();
    method Action PJTAG_TMS(Bit#(1) v);
    method Action PS_CLK(Bit#(1) v);
    method Action PS_PORB(Bit#(1) v);
    method Action PS_SRSTB(Bit#(1) v);
    method Bit#(1) SDIO0_BUSPOW();
    method Bit#(3) SDIO0_BUSVOLT();
    method Action SDIO0_CDN(Bit#(1) v);
    method Bit#(1) SDIO0_CLK();
    method Action SDIO0_CLK_FB(Bit#(1) v);
    method Action SDIO0_CMD_I(Bit#(1) v);
    method Bit#(1) SDIO0_CMD_O();
    method Bit#(1) SDIO0_CMD_T();
    method Action SDIO0_DATA_I(Bit#(4) v);
    method Bit#(4) SDIO0_DATA_O();
    method Bit#(4) SDIO0_DATA_T();
    method Bit#(1) SDIO0_LED();
    method Action SDIO0_WP(Bit#(1) v);
    method Bit#(1) SDIO1_BUSPOW();
    method Bit#(3) SDIO1_BUSVOLT();
    method Action SDIO1_CDN(Bit#(1) v);
    method Bit#(1) SDIO1_CLK();
    method Action SDIO1_CLK_FB(Bit#(1) v);
    method Action SDIO1_CMD_I(Bit#(1) v);
    method Bit#(1) SDIO1_CMD_O();
    method Bit#(1) SDIO1_CMD_T();
    method Action SDIO1_DATA_I(Bit#(4) v);
    method Bit#(4) SDIO1_DATA_O();
    method Bit#(4) SDIO1_DATA_T();
    method Bit#(1) SDIO1_LED();
    method Action SDIO1_WP(Bit#(1) v);
    method Action SPI0_MISO_I(Bit#(1) v);
    method Bit#(1) SPI0_MISO_O();
    method Bit#(1) SPI0_MISO_T();
    method Action SPI0_MOSI_I(Bit#(1) v);
    method Bit#(1) SPI0_MOSI_O();
    method Bit#(1) SPI0_MOSI_T();
    method Action SPI0_SCLK_I(Bit#(1) v);
    method Bit#(1) SPI0_SCLK_O();
    method Bit#(1) SPI0_SCLK_T();
    method Bit#(1) SPI0_SS1_O();
    method Bit#(1) SPI0_SS2_O();
    method Action SPI0_SS_I(Bit#(1) v);
    method Bit#(1) SPI0_SS_O();
    method Bit#(1) SPI0_SS_T();
    method Action SPI1_MISO_I(Bit#(1) v);
    method Bit#(1) SPI1_MISO_O();
    method Bit#(1) SPI1_MISO_T();
    method Action SPI1_MOSI_I(Bit#(1) v);
    method Bit#(1) SPI1_MOSI_O();
    method Bit#(1) SPI1_MOSI_T();
    method Action SPI1_SCLK_I(Bit#(1) v);
    method Bit#(1) SPI1_SCLK_O();
    method Bit#(1) SPI1_SCLK_T();
    method Bit#(1) SPI1_SS1_O();
    method Bit#(1) SPI1_SS2_O();
    method Action SPI1_SS_I(Bit#(1) v);
    method Bit#(1) SPI1_SS_O();
    method Bit#(1) SPI1_SS_T();
    method Action SRAM_INTIN(Bit#(1) v);
    method Action TRACE_CLK(Bit#(1) v);
    method Bit#(1) TRACE_CTL();
    method Bit#(32) TRACE_DATA();
    method Action TTC0_CLK0_IN(Bit#(1) v);
    method Action TTC0_CLK1_IN(Bit#(1) v);
    method Action TTC0_CLK2_IN(Bit#(1) v);
    method Bit#(1) TTC0_WAVE0_OUT();
    method Bit#(1) TTC0_WAVE1_OUT();
    method Bit#(1) TTC0_WAVE2_OUT();
    method Action TTC1_CLK0_IN(Bit#(1) v);
    method Action TTC1_CLK1_IN(Bit#(1) v);
    method Action TTC1_CLK2_IN(Bit#(1) v);
    method Bit#(1) TTC1_WAVE0_OUT();
    method Bit#(1) TTC1_WAVE1_OUT();
    method Bit#(1) TTC1_WAVE2_OUT();
    method Action UART0_CTSN(Bit#(1) v);
    method Action UART0_DCDN(Bit#(1) v);
    method Action UART0_DSRN(Bit#(1) v);
    method Bit#(1) UART0_DTRN();
    method Action UART0_RIN(Bit#(1) v);
    method Bit#(1) UART0_RTSN();
    method Action UART0_RX(Bit#(1) v);
    method Bit#(1) UART0_TX();
    method Action UART1_CTSN(Bit#(1) v);
    method Action UART1_DCDN(Bit#(1) v);
    method Action UART1_DSRN(Bit#(1) v);
    method Bit#(1) UART1_DTRN();
    method Action UART1_RIN(Bit#(1) v);
    method Bit#(1) UART1_RTSN();
    method Action UART1_RX(Bit#(1) v);
    method Bit#(1) UART1_TX();
    method Bit#(2) USB0_PORT_INDCTL();
    method Action USB0_VBUS_PWRFAULT(Bit#(1) v);
    method Bit#(1) USB0_VBUS_PWRSELECT();
    method Bit#(2) USB1_PORT_INDCTL();
    method Action USB1_VBUS_PWRFAULT(Bit#(1) v);
    method Bit#(1) USB1_VBUS_PWRSELECT();
    method Action WDT_CLK_IN(Bit#(1) v);
    method Bit#(1) WDT_RST_OUT();
    method Action S_AXI_HP3_ACLK(Bit#(1) v);
    method Action TRACE_CLK(Bit#(1) v);
    method Bit#(1) TRACE_CTL();
    method Bit#(32) TRACE_DATA();
    method Action TTC0_CLK0_IN(Bit#(1) v);
    method Action TTC0_CLK1_IN(Bit#(1) v);
    method Action TTC0_CLK2_IN(Bit#(1) v);
    method Bit#(1) TTC0_WAVE0_OUT();
    method Bit#(1) TTC0_WAVE1_OUT();
    method Bit#(1) TTC0_WAVE2_OUT();
    method Action TTC1_CLK0_IN(Bit#(1) v);
    method Action TTC1_CLK1_IN(Bit#(1) v);
    method Action TTC1_CLK2_IN(Bit#(1) v);
    method Bit#(1) TTC1_WAVE0_OUT();
    method Bit#(1) TTC1_WAVE1_OUT();
    method Bit#(1) TTC1_WAVE2_OUT();
    method Action UART0_CTSN(Bit#(1) v);
    method Action UART0_DCDN(Bit#(1) v);
    method Action UART0_DSRN(Bit#(1) v);
    method Bit#(1) UART0_DTRN();
    method Action UART0_RIN(Bit#(1) v);
    method Bit#(1) UART0_RTSN();
    method Action UART0_RX(Bit#(1) v);
    method Bit#(1) UART0_TX();
    method Action UART1_CTSN(Bit#(1) v);
    method Action UART1_DCDN(Bit#(1) v);
    method Action UART1_DSRN(Bit#(1) v);
    method Bit#(1) UART1_DTRN();
    method Action UART1_RIN(Bit#(1) v);
    method Bit#(1) UART1_RTSN();
    method Action UART1_RX(Bit#(1) v);
    method Bit#(1) UART1_TX();
    method Bit#(2) USB0_PORT_INDCTL();
    method Action USB0_VBUS_PWRFAULT(Bit#(1) v);
    method Bit#(1) USB0_VBUS_PWRSELECT();
    method Bit#(2) USB1_PORT_INDCTL();
    method Action USB1_VBUS_PWRFAULT(Bit#(1) v);
    method Bit#(1) USB1_VBUS_PWRSELECT();
    method Action WDT_CLK_IN(Bit#(1) v);
    method Bit#(1) WDT_RST_OUT();

   schedule (datain, idatain, inc, ce) CF (datain, idatain, inc, ce);
endmodule


moved to new calculation of startframe (all in bsv)

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

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

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

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

import Vector::*;
import FIFO::*;
import GetPut::*;
import Gearbox::*;
import Clocks :: *;

interface ImageonSerdes;
    method Bit#(1) reset();
    method Bit#(1) auto_align();
    method Bit#(1) align_start();
    method Bit#(1) fifo_enable();
    method Bit#(10) manual_tap();
    method Bit#(10) training();
    method Action iserdes_clk_ready(Bit#(1) ready);
    method Action iserdes_align_busy(Bit#(1) busy);
    method Action iserdes_aligned(Bit#(1) aligned);
endinterface

interface ImageonDecoder;
    method Bit#(1) reset();
    method Bit#(1) enable();
    method Bit#(10) code_ls();
    method Bit#(10) code_le();
    method Bit#(10) code_fs();
    method Action frame_start(Bit#(1) start);
endinterface

interface ImageonTrigger;
    method Bit#(3) enable();
    method Bit#(32) default_freq();
    method Bit#(32) cnt_trigger0high();
    method Bit#(32) cnt_trigger0low();
endinterface

interface ImageonSyncGen;
    //method Bit#(16) delay();
    method Bit#(16) hactive();
    method Bit#(16) hfporch();
    method Bit#(16) hsync();
    method Bit#(16) hbporch();
    method Bit#(16) vactive();
    method Bit#(16) vfporch();
    method Bit#(16) vsync();
    method Bit#(16) vbporch();
endinterface

typedef struct {
    Bit#(1) fsync;
    Bit#(1) vsync;
    Bit#(1) hsync;
    Bit#(1) active_video;
    Bit#(10) video_data;
} XsviData deriving (Bits);

(* always_enabled *)
interface ImageonSensorControl;
    method Bit#(32) get_debugind();
    method Action sframe(Bit#(1) v);
    method Action raw_data(Bit#(50) v);
    method Action raw_empty(Bit#(1) v);
    interface Reset reset;
    interface Reset hdmiReset;
endinterface

(* always_enabled *)
interface ImageonVita;
    method Bit#(1) host_oe();
    interface ImageonSerdes serdes;
    interface ImageonDecoder decoder;
    interface ImageonSyncGen syncgen;
    method Bit#(32) get_debugreq();
    method Action set_debugind(Bit#(32) v);
    interface Reset reset;
endinterface

(* always_enabled *)
interface ImageonVSensor;
    method Bit#(1) foo();
    interface ImageonTrigger trigger;
    interface ImageonDecoder decoder;
    method Bit#(16) syncgen_delay();
endinterface

interface ImageonControl;
    method Action set_iserdes_control(Bit#(32) v);
    method Bit#(32) get_iserdes_control();
    method Action set_decoder_control(Bit#(32) v);
    method Action set_triggen_control(Bit#(32) v);

    method Action set_host_oe(Bit#(1) v);

    method Action set_serdes_reset(Bit#(1) v);
    method Action set_serdes_auto_align(Bit#(1) v);
    method Action set_serdes_align_start(Bit#(1) v);
    method Action set_serdes_fifo_enable(Bit#(1) v);
    method Action set_serdes_manual_tap(Bit#(10) v);
    method Action set_serdes_training(Bit#(10) v);
    method Action set_decoder_reset(Bit#(1) v);
    method Action set_decoder_enable(Bit#(1) v);
    method Action set_decoder_code_ls(Bit#(10) v);
    method Action set_decoder_code_le(Bit#(10) v);
    method Action set_decoder_code_fs(Bit#(10) v);
    method Action set_decoder_code_fe(Bit#(10) v);
    method Action set_decoder_code_bl(Bit#(10) v);
    method Action set_decoder_code_img(Bit#(10) v);
    method Action set_trigger_enable(Bit#(3) v);
    method Action set_trigger_default_freq(Bit#(32) v);
    method Action set_trigger_cnt_trigger0high(Bit#(32) v);
    method Action set_trigger_cnt_trigger0low(Bit#(32) v);
    method Action set_syncgen_delay(Bit#(16) v);
    method Action set_syncgen_hactive(Bit#(16) v);
    method Action set_syncgen_hfporch(Bit#(16) v);
    method Action set_syncgen_hsync(Bit#(16) v);
    method Action set_syncgen_hbporch(Bit#(16) v);
    method Action set_syncgen_vactive(Bit#(16) v);
    method Action set_syncgen_vfporch(Bit#(16) v);
    method Action set_syncgen_vsync(Bit#(16) v);
    method Action set_syncgen_vbporch(Bit#(16) v);
    method Action set_debugreq(Bit#(32) v);
    method Bit#(32) get_debugind();
endinterface

interface ImageonVitaController;
    interface ImageonVita host;
    interface ImageonVSensor hosts;
    interface ImageonControl control;
endinterface

module mkImageonVitaController#(Clock hdmi_clock, Reset hdmi_reset, Clock imageon_clock, Reset imageon_reset)(ImageonVitaController);
    Clock defaultClock <- exposeCurrentClock();
    Reset defaultReset <- exposeCurrentReset;
    Reg#(Bit#(1)) host_oe_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Wire#(Bit#(1)) host_clock_gen_locked_wire <- mkDWire(0);

    Reg#(Bit#(1)) serdes_reset_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(1)) serdes_auto_align_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(1)) serdes_align_start_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(1)) serdes_fifo_enable_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) serdes_manual_tap_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) serdes_training_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Wire#(Bit#(1)) serdes_clk_ready_wire <- mkDWire(0);
    Wire#(Bit#(1)) serdes_align_busy_wire <- mkDWire(0);
    Wire#(Bit#(1)) serdes_aligned_wire <- mkDWire(0);

    Reg#(Bit#(1)) decoder_reset_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(1)) decoder_enable_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) decoder_code_ls_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) decoder_code_le_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) decoder_code_fs_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) decoder_code_ls_regs <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(10)) decoder_code_le_regs <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(10)) decoder_code_fs_regs <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Wire#(Bit#(1)) decoder_frame_start_wire <- mkDWire(0);

    Reg#(Bit#(3)) trigger_enable_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(32)) trigger_default_freq_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(32)) trigger_cnt_trigger0high_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(32)) trigger_cnt_trigger0low_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(16)) syncgen_delay_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(16)) syncgen_hactive_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_hfporch_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_hsync_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_hbporch_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_vactive_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_vfporch_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_vsync_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_vbporch_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(32)) debugreq_value <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(32)) debugind_value <- mkReg(0);

    interface ImageonVita host;
	method Bit#(1) host_oe();
	    return host_oe_reg;
	endmethod
	interface ImageonSerdes serdes;
	    method Bit#(1) reset();
		return serdes_reset_reg;
	    endmethod
	    method Bit#(1) auto_align();
		return serdes_auto_align_reg;
	    endmethod
	    method Bit#(1) align_start();
		return serdes_align_start_reg;
	    endmethod
	    method Bit#(1) fifo_enable();
		return serdes_fifo_enable_reg;
	    endmethod
	    method Bit#(10) manual_tap();
		return serdes_manual_tap_reg;
	    endmethod
	    method Bit#(10) training();
		return serdes_training_reg;
	    endmethod
	    method Action iserdes_clk_ready(Bit#(1) ready);
	        serdes_clk_ready_wire <= ready;
	    endmethod
	    method Action iserdes_align_busy(Bit#(1) busy);
	        serdes_align_busy_wire <= busy;
	    endmethod
	    method Action iserdes_aligned(Bit#(1) aligned);
	        serdes_aligned_wire <= aligned;
	    endmethod
	endinterface
	interface ImageonDecoder decoder;
	    method Bit#(1) reset();
		return decoder_reset_reg;
	    endmethod
	    method Bit#(1) enable();
		return decoder_enable_reg;
	    endmethod
	    method Bit#(10) code_ls();
		return decoder_code_ls_reg;
	    endmethod
	    method Bit#(10) code_le();
		return decoder_code_le_reg;
	    endmethod
	    method Bit#(10) code_fs();
		return decoder_code_fs_reg;
	    endmethod
	    method Action frame_start(Bit#(1) start);
	        decoder_frame_start_wire <= start;
	    endmethod
	endinterface
	interface ImageonSyncGen syncgen;
	    method Bit#(16) hactive();
		return syncgen_hactive_reg;
	    endmethod
	    method Bit#(16) hfporch();
		return syncgen_hfporch_reg;
	    endmethod
	    method Bit#(16) hsync();
		return syncgen_hsync_reg;
	    endmethod
	    method Bit#(16) hbporch();
		return syncgen_hbporch_reg;
	    endmethod
	    method Bit#(16) vactive();
		return syncgen_vactive_reg;
	    endmethod
	    method Bit#(16) vfporch();
		return syncgen_vfporch_reg;
	    endmethod
	    method Bit#(16) vsync();
		return syncgen_vsync_reg;
	    endmethod
	    method Bit#(16) vbporch();
		return syncgen_vbporch_reg;
	    endmethod
	endinterface
        method Bit#(32) get_debugreq();
            return debugreq_value;
	endmethod
        method Action set_debugind(Bit#(32) v);
            debugind_value <= v;
	endmethod
        interface Reset reset = defaultReset;
    endinterface: host

    interface ImageonVSensor hosts;
	method Bit#(1) foo();
	    return 1;
	endmethod
	interface ImageonTrigger trigger;
	    method Bit#(3) enable();
		return trigger_enable_reg;
	    endmethod
	    method Bit#(32) default_freq();
		return trigger_default_freq_reg;
	    endmethod
	    method Bit#(32) cnt_trigger0high();
		return trigger_cnt_trigger0high_reg;
	    endmethod
	    method Bit#(32) cnt_trigger0low();
		return trigger_cnt_trigger0low_reg;
	    endmethod
	endinterface
	interface ImageonDecoder decoder;
	    //method Bit#(1) reset();
		//return decoder_reset_reg;
	    //endmethod
	    //method Bit#(1) enable();
		//return decoder_enable_reg;
	    //endmethod
	    method Bit#(10) code_ls();
		return decoder_code_ls_regs;
	    endmethod
	    method Bit#(10) code_le();
		return decoder_code_le_regs;
	    endmethod
	    method Bit#(10) code_fs();
		return decoder_code_fs_regs;
	    endmethod
	    //method Action frame_start(Bit#(1) start);
	        //decoder_frame_start_wire <= start;
	    //endmethod
	endinterface
	method Bit#(16) syncgen_delay();
	    return syncgen_delay_reg;
	endmethod
    endinterface: hosts

    interface ImageonControl control;
	method Action set_iserdes_control(Bit#(32) v);
	    serdes_reset_reg <= v[0];
	    serdes_auto_align_reg <= v[1];
	    serdes_align_start_reg <= v[2];
	    serdes_fifo_enable_reg <= v[3];
	endmethod
	method Bit#(32) get_iserdes_control();
	    let v = 0;
	    v[8] = serdes_clk_ready_wire;
	    v[9] = serdes_align_busy_wire;
	    v[10] = serdes_aligned_wire;
	    return v;
	endmethod
	method Action set_decoder_control(Bit#(32) v);
	    decoder_reset_reg <= v[0];
	    decoder_enable_reg <= v[1];
	endmethod
// TRIGGEN_CONTROL
// [ 2: 0] TRIGGEN_ENABLE
// [ 6: 4] TRIGGEN_SYNC2READOUT
// [    8] TRIGGEN_READOUTTRIGGER
// [   16] TRIGGEN_EXT_POLARITY
// [   24] TRIGGEN_CNT_UPDATE
// [30:28] TRIGGEN_GEN_POLARITY
	method Action set_triggen_control(Bit#(32) v);
	    trigger_enable_reg <= v[2:0];
	endmethod

	method Action set_host_oe(Bit#(1) v);
	    host_oe_reg <= ~v;
	endmethod

	method Action set_serdes_reset(Bit#(1) v);
	    serdes_reset_reg <= v;
	endmethod
	method Action set_serdes_auto_align(Bit#(1) v);
	    serdes_auto_align_reg <= v;
	endmethod
	method Action set_serdes_align_start(Bit#(1) v);
	    serdes_align_start_reg <= v;
	endmethod
	method Action set_serdes_fifo_enable(Bit#(1) v);
	    serdes_fifo_enable_reg <= v;
	endmethod
	method Action set_serdes_manual_tap(Bit#(10) v);
	    serdes_manual_tap_reg <= v;
	endmethod
	method Action set_serdes_training(Bit#(10) v);
	    serdes_training_reg <= v;
	endmethod
	method Action set_decoder_reset(Bit#(1) v);
	    decoder_reset_reg <= v;
	endmethod
	method Action set_decoder_enable(Bit#(1) v);
	    decoder_enable_reg <= v;
	endmethod
	method Action set_decoder_code_ls(Bit#(10) v);
	    decoder_code_ls_reg <= v;
	    decoder_code_ls_regs <= v;
	endmethod
	method Action set_decoder_code_le(Bit#(10) v);
	    decoder_code_le_reg <= v;
	    decoder_code_le_regs <= v;
	endmethod
	method Action set_decoder_code_fs(Bit#(10) v);
	    decoder_code_fs_reg <= v;
	    decoder_code_fs_regs <= v;
	endmethod
	method Action set_decoder_code_fe(Bit#(10) v);
	endmethod
	method Action set_decoder_code_bl(Bit#(10) v);
	endmethod
	method Action set_decoder_code_img(Bit#(10) v);
	endmethod
	method Action set_trigger_enable(Bit#(3) v);
	    trigger_enable_reg <= v;
	endmethod
	method Action set_trigger_default_freq(Bit#(32) v);
	    trigger_default_freq_reg <= v;
	endmethod
	method Action set_trigger_cnt_trigger0high(Bit#(32) v);
	    trigger_cnt_trigger0high_reg <= v;
	endmethod
	method Action set_trigger_cnt_trigger0low(Bit#(32) v);
	    trigger_cnt_trigger0low_reg <= v;
	endmethod
	method Action set_syncgen_delay(Bit#(16) v);
	    syncgen_delay_reg <= v;
	endmethod
	method Action set_syncgen_hactive(Bit#(16) v);
	    syncgen_hactive_reg <= v;
	endmethod
	method Action set_syncgen_hfporch(Bit#(16) v);
	    syncgen_hfporch_reg <= v;
	endmethod
	method Action set_syncgen_hsync(Bit#(16) v);
	    syncgen_hsync_reg <= v;
	endmethod
	method Action set_syncgen_hbporch(Bit#(16) v);
	    syncgen_hbporch_reg <= v;
	endmethod
	method Action set_syncgen_vactive(Bit#(16) v);
	    syncgen_vactive_reg <= v;
	endmethod
	method Action set_syncgen_vfporch(Bit#(16) v);
	    syncgen_vfporch_reg <= v;
	endmethod
	method Action set_syncgen_vsync(Bit#(16) v);
	    syncgen_vsync_reg <= v;
	endmethod
	method Action set_syncgen_vbporch(Bit#(16) v);
	    syncgen_vbporch_reg <= v;
	endmethod
        method Action set_debugreq(Bit#(32) v);
            debugreq_value <= v;
	endmethod
        method Bit#(32) get_debugind();
            return debugind_value;
	endmethod
    endinterface
endmodule

interface ImageonXsviFromSensor;
    interface Get#(XsviData) out;
endinterface

interface ImageonSensor;
    interface ImageonSensorControl in;
    interface Get#(Bit#(1)) out;
    method Bit#(1)get_framesync();
    method Bit#(40)get_data();
endinterface

typedef enum { Idle, Active, FrontP, Sync, BackP} State deriving (Bits,Eq);
typedef enum { TIdle, TSend, TWait} TState deriving (Bits,Eq);

module mkImageonSensor#(Clock hdmi_clock, Reset hdmi_reset, ImageonVSensor host)(ImageonSensor);
    Clock defaultClock <- exposeCurrentClock();
    Reset defaultReset <- exposeCurrentReset();

    Reg#(TState)   tstate <- mkReg(TIdle);
    Reg#(Bit#(1)) sframe_wire <- mkReg(0);
    Reg#(Bit#(1)) sframe_new_wire <- mkReg(0);
    Reg#(Bit#(1))  fs2 <- mkReg(0);
    Reg#(Bit#(16)) frame_delay <- mkReg(0);
    Reg#(Bit#(1))  frame_run <- mkReg(0);
    Reg#(Bit#(32)) tcounter <- mkReg(0);
    Reg#(Bit#(32)) diff <- mkReg(0);
    Reg#(Bit#(1))  framestart_delay_reg <- mkReg(0);
    Reg#(Bit#(32)) debugind_value <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) sync_delay_reg <- mkReg(0);
    Wire#(Bit#(50)) raw_data_wire <- mkDWire(0);
    Reg#(Bit#(50)) raw_data_reg <- mkReg(0);
    Reg#(Bit#(40)) dataout_reg <- mkReg(0);
    Reg#(Bit#(50)) raw_data_delay_reg <- mkReg(0);
    Wire#(Bit#(1)) raw_empty_wire <- mkDWire(0);
    Reg#(Bit#(1)) raw_empty_reg <- mkReg(0);
    Reg#(Bit#(1)) remapkernel_reg <- mkReg(0);
    Reg#(Bit#(1)) imgdatavalid_reg <- mkReg(0);
    Reg#(Bit#(8)) dcount <- mkReg(0);

    rule tcalc;
        let tc = tcounter - 1;
        let ts = tstate;
        if (tstate == TIdle && tcounter == 0)
            begin
            tc = host.trigger.cnt_trigger0high();
            ts = TSend;
            end
        if (tstate == TSend && tcounter == 0)
            begin
            tc = host.trigger.cnt_trigger0low();
            ts = TWait;
            end
        if (tstate == TWait && tcounter == 0)
            begin
            ts = TIdle;
            tc = host.trigger.default_freq();
            end
        tcounter  <= tc;
        tstate  <= ts;
    endrule

    rule sframe_calc;
        let fd = frame_delay+1;
        let fr = frame_run;
        let fstemp = 0;
        if (sframe_new_wire == 1)
            begin
            fr = 1;
            fd = 0;
            end
        if (frame_run == 1 && frame_delay == host.syncgen_delay() )
            begin
            fr = 0;
            fstemp = 1;
            end
        frame_delay <= fd;
        frame_run <= fr;
        fs2 <= fstemp;
    endrule

    rule update_debug;
        //let startframe_wire     = pack(raw_data_delay_reg[9:0] == host.decoder.code_fs() && raw_data_reg[9:0] == 10'h0);
        let dval = diff;
        dval = {dcount, diff[21:0], sframe_wire, sframe_new_wire};
        if (sframe_wire != sframe_new_wire)
            begin
            dcount <= dcount + 1;
            end
        if (diff[17] == 1)
            begin
            debugind_value <= diff;
            dval = 0;
            end
        diff <= dval;
    endrule

    rule data_pipeline;
        if (raw_empty_wire == 0)
            begin
            raw_data_reg <= raw_data_wire;
            raw_data_delay_reg <= raw_data_reg;
            end
        raw_empty_reg <= raw_empty_wire;
    endrule

    rule calculate_framedata;
        let startimageline_wire = pack(raw_data_delay_reg[9:0] == host.decoder.code_ls());
        let endimageline_wire   = pack(raw_data_delay_reg[9:0] == host.decoder.code_le());
        let datain_temp = raw_data_reg[49:10];
        let idv = imgdatavalid_reg;
        let dor = dataout_reg;
            //WRITE_DATA <= 0;
            if (raw_empty_reg == 0)
                begin
                if (imgdatavalid_reg == 1)
                    begin
                    if (remapkernel_reg == 0)
                        begin
                        dor[39: 30] = datain_temp[9: 0];
                        dor[29: 20] = datain_temp[19: 10];
                        dor[19: 10] = datain_temp[29: 20];
                        dor[ 9:  0] = datain_temp[39: 30];
                        end
                    else
                        begin
                        dor[39: 30] = datain_temp[39: 30];
                        dor[29: 20] = datain_temp[29: 20];
                        dor[19: 10] = datain_temp[19: 10];
                        dor[ 9:  0] = datain_temp[9: 0];
                        end
                    //WRITE_DATA <= 1;
                    remapkernel_reg <= ~ remapkernel_reg;
                    if (endimageline_wire == 1 && startimageline_wire == 0)
                        begin
                        idv = 0;
                        end
                    end
                else if (startimageline_wire == 1)
                    begin
                    idv = 1;
                    end
                end
        imgdatavalid_reg <= idv;
        dataout_reg <= dor;
        sframe_new_wire <= pack(raw_data_delay_reg[9:0] == host.decoder.code_fs() && raw_data_reg[9:0] == 10'h0);
    endrule

    interface ImageonSensorControl in;
	method Action sframe(Bit#(1) v);
            sframe_wire <= v;
	endmethod
        method Action raw_data(Bit#(50) v);
            raw_data_wire <= v;
	endmethod
        method Action raw_empty(Bit#(1) v);
            raw_empty_wire <= v;
	endmethod
        method Bit#(32) get_debugind();
            return debugind_value;
	endmethod
	interface Reset reset = defaultReset;
	interface Reset hdmiReset = hdmi_reset;
    endinterface: in
    interface Get out;
	method ActionValue#(Bit#(1)) get();
	    return 1;
	endmethod
    endinterface: out

    method Bit#(1)get_framesync();
        return fs2;
    endmethod
    method Bit#(40)get_data();
        return dataout_reg;
    endmethod
endmodule

module mkImageonXsviFromSensor#(Clock imageon_clock, Reset imageon_reset, ImageonVita host, ImageonSensor sensor)(ImageonXsviFromSensor);
    Clock defaultClock <- exposeCurrentClock();
    Reset defaultReset <- exposeCurrentReset();

    Gearbox#(4, 1, Bit#(10)) dataGearbox <- mkNto1Gearbox(imageon_clock, imageon_reset, defaultClock, defaultReset);
    Gearbox#(4, 1, Bit#(1))  syncGearbox <- mkNto1Gearbox(imageon_clock, imageon_reset, defaultClock, defaultReset);

    Reg#(State)    hstate <- mkReg(Idle);
    Reg#(State)    vstate <- mkReg(Idle);
    Reg#(Bit#(1))  active_video_reg <- mkReg(0);
    Reg#(Bit#(16)) vsync_count <- mkReg(0);
    Reg#(Bit#(16)) hsync_count <- mkReg(0);
    Reg#(Bit#(10)) videodata <- mkReg(0);
    Reg#(Bit#(1))  framestart_new <- mkReg(0);

    rule start_fsm if (framestart_new == 1);
        vsync_count <= 0;
        hsync_count <= 0;
        hstate <= Active;
        vstate <= Active;
    endrule

    rule sync_fsm if (framestart_new != 1);
        let hs = hstate;
        let vs = vstate;
        let hc = hsync_count;
        let vc = vsync_count;

        hc = hc + 1;
        if (hstate == FrontP && hsync_count >= host.syncgen.hfporch() - 1)
            begin
            hc = 0;
            hs = Sync;
            vc = vc + 1;
            if (vstate == Active && vsync_count >= host.syncgen.vactive() - 1)
                begin
                vc = 0;
                vs = FrontP;
                end
            if (vstate == FrontP && vsync_count >= host.syncgen.vfporch() - 1)
                begin
                vc = 0;
                vs = Sync;
                end
            if (vstate == Sync && vsync_count >= host.syncgen.vsync() - 1)
                begin
                vc = 0;
                vs = BackP;
                end
            end
        if (hstate == Sync && hsync_count >= host.syncgen.hsync() - 1)
            begin
            hc = 0;
            hs = BackP;
            end
        if (hstate == BackP && hsync_count >= host.syncgen.hbporch() - 1)
            begin
            hc = 0;
            hs = Active;
            end
        if (hstate == Active && hsync_count >= host.syncgen.hactive() - 1)
            begin
            hc = 0;
            hs = FrontP;
            end

        hstate <= hs;
        vstate <= vs;
        hsync_count <= hc;
        vsync_count <= vc;
        active_video_reg <= pack(hstate == Active && vstate == Active);
    endrule

    rule update_framestart;
	syncGearbox.deq;
        framestart_new <= syncGearbox.first[0];
    endrule

    rule update_videodata if (active_video_reg == 1);
	dataGearbox.deq;
        videodata <= dataGearbox.first[0];
    endrule

    rule receive_framestart;
	Vector#(4, Bit#(1)) in = replicate(0);
	// zero'th element shifted out first
	in[1] = sensor.get_framesync();
	syncGearbox.enq(in);
    endrule

    rule receive_data;
	    // least signifcant 10 bits shifted out first
	    Vector#(4, Bit#(10)) in = unpack(sensor.get_data());
	    dataGearbox.enq(in);
    endrule

    interface Get out;
	method ActionValue#(XsviData) get();
	    return XsviData {
		fsync: framestart_new,
		vsync: pack(vstate == Sync),
		hsync: pack(hstate == Sync),
		active_video: active_video_reg,
		video_data: videodata
	    };
	endmethod
    endinterface: out
endmodule

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

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

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

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

import Vector::*;
import FIFO::*;
import GetPut::*;
import Gearbox::*;
import Clocks :: *;

interface ImageonSerdes;
    method Bit#(1) reset();
    method Bit#(1) auto_align();
    method Bit#(1) align_start();
    method Bit#(1) fifo_enable();
    method Bit#(10) manual_tap();
    method Bit#(10) training();
    method Action iserdes_clk_ready(Bit#(1) ready);
    method Action iserdes_align_busy(Bit#(1) busy);
    method Action iserdes_aligned(Bit#(1) aligned);
endinterface

interface ImageonDecoder;
    method Bit#(1) reset();
    method Bit#(1) enable();
    method Bit#(10) code_ls();
    method Bit#(10) code_le();
    method Bit#(10) code_fs();
    method Action frame_start(Bit#(1) start);
endinterface

interface ImageonTrigger;
    method Bit#(3) enable();
    method Bit#(32) default_freq();
    method Bit#(32) cnt_trigger0high();
    method Bit#(32) cnt_trigger0low();
endinterface

interface ImageonSyncGen;
    //method Bit#(16) delay();
    method Bit#(16) hactive();
    method Bit#(16) hfporch();
    method Bit#(16) hsync();
    method Bit#(16) hbporch();
    method Bit#(16) vactive();
    method Bit#(16) vfporch();
    method Bit#(16) vsync();
    method Bit#(16) vbporch();
endinterface

typedef struct {
    Bit#(1) fsync;
    Bit#(1) vsync;
    Bit#(1) hsync;
    Bit#(1) active_video;
    Bit#(10) video_data;
} XsviData deriving (Bits);

(* always_enabled *)
interface ImageonSensorControl;
    method Bit#(32) get_debugind();
    method Action sframe(Bit#(1) v);
    method Action raw_data(Bit#(50) v);
    method Action raw_empty(Bit#(1) v);
    interface Reset reset;
    interface Reset hdmiReset;
endinterface

(* always_enabled *)
interface ImageonVita;
    method Bit#(1) host_oe();
    interface ImageonSerdes serdes;
    interface ImageonDecoder decoder;
    interface ImageonSyncGen syncgen;
    method Bit#(32) get_debugreq();
    method Action set_debugind(Bit#(32) v);
    interface Reset reset;
endinterface

(* always_enabled *)
interface ImageonVSensor;
    method Bit#(1) foo();
    interface ImageonTrigger trigger;
    interface ImageonDecoder decoder;
    method Bit#(16) syncgen_delay();
endinterface

interface ImageonControl;
    method Action set_iserdes_control(Bit#(32) v);
    method Bit#(32) get_iserdes_control();
    method Action set_decoder_control(Bit#(32) v);
    method Action set_triggen_control(Bit#(32) v);

    method Action set_host_oe(Bit#(1) v);

    method Action set_serdes_reset(Bit#(1) v);
    method Action set_serdes_auto_align(Bit#(1) v);
    method Action set_serdes_align_start(Bit#(1) v);
    method Action set_serdes_fifo_enable(Bit#(1) v);
    method Action set_serdes_manual_tap(Bit#(10) v);
    method Action set_serdes_training(Bit#(10) v);
    method Action set_decoder_reset(Bit#(1) v);
    method Action set_decoder_enable(Bit#(1) v);
    method Action set_decoder_code_ls(Bit#(10) v);
    method Action set_decoder_code_le(Bit#(10) v);
    method Action set_decoder_code_fs(Bit#(10) v);
    method Action set_decoder_code_fe(Bit#(10) v);
    method Action set_decoder_code_bl(Bit#(10) v);
    method Action set_decoder_code_img(Bit#(10) v);
    method Action set_trigger_enable(Bit#(3) v);
    method Action set_trigger_default_freq(Bit#(32) v);
    method Action set_trigger_cnt_trigger0high(Bit#(32) v);
    method Action set_trigger_cnt_trigger0low(Bit#(32) v);
    method Action set_syncgen_delay(Bit#(16) v);
    method Action set_syncgen_hactive(Bit#(16) v);
    method Action set_syncgen_hfporch(Bit#(16) v);
    method Action set_syncgen_hsync(Bit#(16) v);
    method Action set_syncgen_hbporch(Bit#(16) v);
    method Action set_syncgen_vactive(Bit#(16) v);
    method Action set_syncgen_vfporch(Bit#(16) v);
    method Action set_syncgen_vsync(Bit#(16) v);
    method Action set_syncgen_vbporch(Bit#(16) v);
    method Action set_debugreq(Bit#(32) v);
    method Bit#(32) get_debugind();
endinterface

interface ImageonVitaController;
    interface ImageonVita host;
    interface ImageonVSensor hosts;
    interface ImageonControl control;
endinterface

module mkImageonVitaController#(Clock hdmi_clock, Reset hdmi_reset, Clock imageon_clock, Reset imageon_reset)(ImageonVitaController);
    Clock defaultClock <- exposeCurrentClock();
    Reset defaultReset <- exposeCurrentReset;
    Reg#(Bit#(1)) host_oe_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Wire#(Bit#(1)) host_clock_gen_locked_wire <- mkDWire(0);

    Reg#(Bit#(1)) serdes_reset_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(1)) serdes_auto_align_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(1)) serdes_align_start_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(1)) serdes_fifo_enable_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) serdes_manual_tap_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) serdes_training_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Wire#(Bit#(1)) serdes_clk_ready_wire <- mkDWire(0);
    Wire#(Bit#(1)) serdes_align_busy_wire <- mkDWire(0);
    Wire#(Bit#(1)) serdes_aligned_wire <- mkDWire(0);

    Reg#(Bit#(1)) decoder_reset_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(1)) decoder_enable_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) decoder_code_ls_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) decoder_code_le_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) decoder_code_fs_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) decoder_code_ls_regs <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(10)) decoder_code_le_regs <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(10)) decoder_code_fs_regs <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Wire#(Bit#(1)) decoder_frame_start_wire <- mkDWire(0);

    Reg#(Bit#(3)) trigger_enable_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(32)) trigger_default_freq_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(32)) trigger_cnt_trigger0high_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(32)) trigger_cnt_trigger0low_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(16)) syncgen_delay_reg <- mkSyncReg(0, defaultClock, defaultReset, imageon_clock);
    Reg#(Bit#(16)) syncgen_hactive_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_hfporch_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_hsync_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_hbporch_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_vactive_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_vfporch_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_vsync_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(16)) syncgen_vbporch_reg <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(32)) debugreq_value <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(32)) debugind_value <- mkReg(0);

    interface ImageonVita host;
	method Bit#(1) host_oe();
	    return host_oe_reg;
	endmethod
	interface ImageonSerdes serdes;
	    method Bit#(1) reset();
		return serdes_reset_reg;
	    endmethod
	    method Bit#(1) auto_align();
		return serdes_auto_align_reg;
	    endmethod
	    method Bit#(1) align_start();
		return serdes_align_start_reg;
	    endmethod
	    method Bit#(1) fifo_enable();
		return serdes_fifo_enable_reg;
	    endmethod
	    method Bit#(10) manual_tap();
		return serdes_manual_tap_reg;
	    endmethod
	    method Bit#(10) training();
		return serdes_training_reg;
	    endmethod
	    method Action iserdes_clk_ready(Bit#(1) ready);
	        serdes_clk_ready_wire <= ready;
	    endmethod
	    method Action iserdes_align_busy(Bit#(1) busy);
	        serdes_align_busy_wire <= busy;
	    endmethod
	    method Action iserdes_aligned(Bit#(1) aligned);
	        serdes_aligned_wire <= aligned;
	    endmethod
	endinterface
	interface ImageonDecoder decoder;
	    method Bit#(1) reset();
		return decoder_reset_reg;
	    endmethod
	    method Bit#(1) enable();
		return decoder_enable_reg;
	    endmethod
	    method Bit#(10) code_ls();
		return decoder_code_ls_reg;
	    endmethod
	    method Bit#(10) code_le();
		return decoder_code_le_reg;
	    endmethod
	    method Bit#(10) code_fs();
		return decoder_code_fs_reg;
	    endmethod
	    method Action frame_start(Bit#(1) start);
	        decoder_frame_start_wire <= start;
	    endmethod
	endinterface
	interface ImageonSyncGen syncgen;
	    method Bit#(16) hactive();
		return syncgen_hactive_reg;
	    endmethod
	    method Bit#(16) hfporch();
		return syncgen_hfporch_reg;
	    endmethod
	    method Bit#(16) hsync();
		return syncgen_hsync_reg;
	    endmethod
	    method Bit#(16) hbporch();
		return syncgen_hbporch_reg;
	    endmethod
	    method Bit#(16) vactive();
		return syncgen_vactive_reg;
	    endmethod
	    method Bit#(16) vfporch();
		return syncgen_vfporch_reg;
	    endmethod
	    method Bit#(16) vsync();
		return syncgen_vsync_reg;
	    endmethod
	    method Bit#(16) vbporch();
		return syncgen_vbporch_reg;
	    endmethod
	endinterface
        method Bit#(32) get_debugreq();
            return debugreq_value;
	endmethod
        method Action set_debugind(Bit#(32) v);
            debugind_value <= v;
	endmethod
        interface Reset reset = defaultReset;
    endinterface: host

    interface ImageonVSensor hosts;
	method Bit#(1) foo();
	    return 1;
	endmethod
	interface ImageonTrigger trigger;
	    method Bit#(3) enable();
		return trigger_enable_reg;
	    endmethod
	    method Bit#(32) default_freq();
		return trigger_default_freq_reg;
	    endmethod
	    method Bit#(32) cnt_trigger0high();
		return trigger_cnt_trigger0high_reg;
	    endmethod
	    method Bit#(32) cnt_trigger0low();
		return trigger_cnt_trigger0low_reg;
	    endmethod
	endinterface
	interface ImageonDecoder decoder;
	    //method Bit#(1) reset();
		//return decoder_reset_reg;
	    //endmethod
	    //method Bit#(1) enable();
		//return decoder_enable_reg;
	    //endmethod
	    method Bit#(10) code_ls();
		return decoder_code_ls_regs;
	    endmethod
	    method Bit#(10) code_le();
		return decoder_code_le_regs;
	    endmethod
	    method Bit#(10) code_fs();
		return decoder_code_fs_regs;
	    endmethod
	    //method Action frame_start(Bit#(1) start);
	        //decoder_frame_start_wire <= start;
	    //endmethod
	endinterface
	method Bit#(16) syncgen_delay();
	    return syncgen_delay_reg;
	endmethod
    endinterface: hosts

    interface ImageonControl control;
	method Action set_iserdes_control(Bit#(32) v);
	    serdes_reset_reg <= v[0];
	    serdes_auto_align_reg <= v[1];
	    serdes_align_start_reg <= v[2];
	    serdes_fifo_enable_reg <= v[3];
	endmethod
	method Bit#(32) get_iserdes_control();
	    let v = 0;
	    v[8] = serdes_clk_ready_wire;
	    v[9] = serdes_align_busy_wire;
	    v[10] = serdes_aligned_wire;
	    return v;
	endmethod
	method Action set_decoder_control(Bit#(32) v);
	    decoder_reset_reg <= v[0];
	    decoder_enable_reg <= v[1];
	endmethod
// TRIGGEN_CONTROL
// [ 2: 0] TRIGGEN_ENABLE
// [ 6: 4] TRIGGEN_SYNC2READOUT
// [    8] TRIGGEN_READOUTTRIGGER
// [   16] TRIGGEN_EXT_POLARITY
// [   24] TRIGGEN_CNT_UPDATE
// [30:28] TRIGGEN_GEN_POLARITY
	method Action set_triggen_control(Bit#(32) v);
	    trigger_enable_reg <= v[2:0];
	endmethod

	method Action set_host_oe(Bit#(1) v);
	    host_oe_reg <= ~v;
	endmethod

	method Action set_serdes_reset(Bit#(1) v);
	    serdes_reset_reg <= v;
	endmethod
	method Action set_serdes_auto_align(Bit#(1) v);
	    serdes_auto_align_reg <= v;
	endmethod
	method Action set_serdes_align_start(Bit#(1) v);
	    serdes_align_start_reg <= v;
	endmethod
	method Action set_serdes_fifo_enable(Bit#(1) v);
	    serdes_fifo_enable_reg <= v;
	endmethod
	method Action set_serdes_manual_tap(Bit#(10) v);
	    serdes_manual_tap_reg <= v;
	endmethod
	method Action set_serdes_training(Bit#(10) v);
	    serdes_training_reg <= v;
	endmethod
	method Action set_decoder_reset(Bit#(1) v);
	    decoder_reset_reg <= v;
	endmethod
	method Action set_decoder_enable(Bit#(1) v);
	    decoder_enable_reg <= v;
	endmethod
	method Action set_decoder_code_ls(Bit#(10) v);
	    decoder_code_ls_reg <= v;
	    decoder_code_ls_regs <= v;
	endmethod
	method Action set_decoder_code_le(Bit#(10) v);
	    decoder_code_le_reg <= v;
	    decoder_code_le_regs <= v;
	endmethod
	method Action set_decoder_code_fs(Bit#(10) v);
	    decoder_code_fs_reg <= v;
	    decoder_code_fs_regs <= v;
	endmethod
	method Action set_decoder_code_fe(Bit#(10) v);
	endmethod
	method Action set_decoder_code_bl(Bit#(10) v);
	endmethod
	method Action set_decoder_code_img(Bit#(10) v);
	endmethod
	method Action set_trigger_enable(Bit#(3) v);
	    trigger_enable_reg <= v;
	endmethod
	method Action set_trigger_default_freq(Bit#(32) v);
	    trigger_default_freq_reg <= v;
	endmethod
	method Action set_trigger_cnt_trigger0high(Bit#(32) v);
	    trigger_cnt_trigger0high_reg <= v;
	endmethod
	method Action set_trigger_cnt_trigger0low(Bit#(32) v);
	    trigger_cnt_trigger0low_reg <= v;
	endmethod
	method Action set_syncgen_delay(Bit#(16) v);
	    syncgen_delay_reg <= v;
	endmethod
	method Action set_syncgen_hactive(Bit#(16) v);
	    syncgen_hactive_reg <= v;
	endmethod
	method Action set_syncgen_hfporch(Bit#(16) v);
	    syncgen_hfporch_reg <= v;
	endmethod
	method Action set_syncgen_hsync(Bit#(16) v);
	    syncgen_hsync_reg <= v;
	endmethod
	method Action set_syncgen_hbporch(Bit#(16) v);
	    syncgen_hbporch_reg <= v;
	endmethod
	method Action set_syncgen_vactive(Bit#(16) v);
	    syncgen_vactive_reg <= v;
	endmethod
	method Action set_syncgen_vfporch(Bit#(16) v);
	    syncgen_vfporch_reg <= v;
	endmethod
	method Action set_syncgen_vsync(Bit#(16) v);
	    syncgen_vsync_reg <= v;
	endmethod
	method Action set_syncgen_vbporch(Bit#(16) v);
	    syncgen_vbporch_reg <= v;
	endmethod
        method Action set_debugreq(Bit#(32) v);
            debugreq_value <= v;
	endmethod
        method Bit#(32) get_debugind();
            return debugind_value;
	endmethod
    endinterface
endmodule

interface ImageonXsviFromSensor;
    interface Get#(XsviData) out;
endinterface

interface ImageonSensor;
    interface ImageonSensorControl in;
    interface Get#(Bit#(1)) out;
    method Bit#(1)get_framesync();
    method Bit#(40)get_data();
endinterface

typedef enum { Idle, Active, FrontP, Sync, BackP} State deriving (Bits,Eq);
typedef enum { TIdle, TSend, TWait} TState deriving (Bits,Eq);

module mkImageonSensor#(Clock hdmi_clock, Reset hdmi_reset, ImageonVSensor host)(ImageonSensor);
    Clock defaultClock <- exposeCurrentClock();
    Reset defaultReset <- exposeCurrentReset();

    Reg#(TState)   tstate <- mkReg(TIdle);
    Wire#(Bit#(1)) sframe_wire <- mkDWire(0);
    Reg#(Bit#(1))  fs2 <- mkReg(0);
    Reg#(Bit#(16)) frame_delay <- mkReg(0);
    Reg#(Bit#(1))  frame_run <- mkReg(0);
    Reg#(Bit#(32)) tcounter <- mkReg(0);
    Reg#(Bit#(32)) diff <- mkReg(0);
    Reg#(Bit#(1))  framestart_delay_reg <- mkReg(0);
    Reg#(Bit#(32)) debugind_value <- mkSyncReg(0, defaultClock, defaultReset, hdmi_clock);
    Reg#(Bit#(10)) sync_delay_reg <- mkReg(0);
    Wire#(Bit#(50)) raw_data_wire <- mkDWire(0);
    Reg#(Bit#(50)) raw_data_reg <- mkReg(0);
    Reg#(Bit#(40)) dataout_reg <- mkReg(0);
    Reg#(Bit#(50)) raw_data_delay_reg <- mkReg(0);
    Wire#(Bit#(1)) raw_empty_wire <- mkDWire(0);
    Reg#(Bit#(1)) raw_empty_reg <- mkReg(0);
    Reg#(Bit#(1)) remapkernel_reg <- mkReg(0);
    Reg#(Bit#(1)) imgdatavalid_reg <- mkReg(0);
    //Wire#(Bit#(1)) startframe_wire <- mkDWire(0);
    //Wire#(Bit#(1)) startimageline_wire <- mkDWire(0);
    //Wire#(Bit#(1)) endimageline_wire <- mkDWire(0);

    rule tcalc;
        let tc = tcounter - 1;
        let ts = tstate;
        if (tstate == TIdle && tcounter == 0)
            begin
            tc = host.trigger.cnt_trigger0high();
            ts = TSend;
            end
        if (tstate == TSend && tcounter == 0)
            begin
            tc = host.trigger.cnt_trigger0low();
            ts = TWait;
            end
        if (tstate == TWait && tcounter == 0)
            begin
            ts = TIdle;
            tc = host.trigger.default_freq();
            end
        tcounter  <= tc;
        tstate  <= ts;
    endrule

    rule sframe_calc;
        let fd = frame_delay+1;
        let fr = frame_run;
        let fstemp = 0;
        if (sframe_wire == 1)
            begin
            fr = 1;
            fd = 0;
            end
        if (frame_run == 1 && frame_delay == host.syncgen_delay() + 1 )
            begin
            fr = 0;
            fstemp = 1;
            end
        frame_delay <= fd;
        frame_run <= fr;
        fs2 <= fstemp;
    endrule

    rule update_debug;
        let dval = diff;
        //dval = {diff[29:0], framestart_reg, fs2};
        if (diff[17] == 1)
            begin
            debugind_value <= diff;
            dval = 0;
            end
        diff <= dval;
    endrule

    rule data_pipeline;
        if (raw_empty_wire == 0)
            begin
            raw_data_reg <= raw_data_wire;
            raw_data_delay_reg <= raw_data_reg;
            end
        raw_empty_reg <= raw_empty_wire;
    endrule

    rule calculate_framedata;
        let startframe_wire     = pack(raw_data_delay_reg[9:0] == host.decoder.code_fs() && raw_data_reg[9:0] == 10'h0);
        let startimageline_wire = pack(raw_data_delay_reg[9:0] == host.decoder.code_ls());
        let endimageline_wire   = pack(raw_data_delay_reg[9:0] == host.decoder.code_le());
        let datain_temp = raw_data_reg[49:10];
        let idv = imgdatavalid_reg;
        let dor = dataout_reg;
            //WRITE_DATA <= 0;
            if (raw_empty_reg == 0)
                begin
                if (imgdatavalid_reg == 1)
                    begin
                    if (remapkernel_reg == 0)
                        begin
                        dor[39: 30] = datain_temp[9: 0];
                        dor[29: 20] = datain_temp[19: 10];
                        dor[19: 10] = datain_temp[29: 20];
                        dor[ 9:  0] = datain_temp[39: 30];
                        end
                    else
                        begin
                        dor[39: 30] = datain_temp[39: 30];
                        dor[29: 20] = datain_temp[29: 20];
                        dor[19: 10] = datain_temp[19: 10];
                        dor[ 9:  0] = datain_temp[9: 0];
                        end
                    //WRITE_DATA <= 1;
                    remapkernel_reg <= ~ remapkernel_reg;
                    if (endimageline_wire == 1 && startimageline_wire == 0)
                        begin
                        idv = 0;
                        end
                    end
                else if (startimageline_wire == 1)
                    begin
                    idv = 1;
                    end
                end
        imgdatavalid_reg <= idv;
        dataout_reg <= dor;
    endrule

    interface ImageonSensorControl in;
	method Action sframe(Bit#(1) v);
            sframe_wire <= v;
	endmethod
        method Action raw_data(Bit#(50) v);
            raw_data_wire <= v;
	endmethod
        method Action raw_empty(Bit#(1) v);
            raw_empty_wire <= v;
	endmethod
        method Bit#(32) get_debugind();
            return debugind_value;
	endmethod
	interface Reset reset = defaultReset;
	interface Reset hdmiReset = hdmi_reset;
    endinterface: in
    interface Get out;
	method ActionValue#(Bit#(1)) get();
	    return 1;
	endmethod
    endinterface: out

    method Bit#(1)get_framesync();
        return fs2;
    endmethod
    method Bit#(40)get_data();
        return dataout_reg;
    endmethod
endmodule

module mkImageonXsviFromSensor#(Clock imageon_clock, Reset imageon_reset, ImageonVita host, ImageonSensor sensor)(ImageonXsviFromSensor);
    Clock defaultClock <- exposeCurrentClock();
    Reset defaultReset <- exposeCurrentReset();

    Gearbox#(4, 1, Bit#(10)) dataGearbox <- mkNto1Gearbox(imageon_clock, imageon_reset, defaultClock, defaultReset);
    Gearbox#(4, 1, Bit#(1))  syncGearbox <- mkNto1Gearbox(imageon_clock, imageon_reset, defaultClock, defaultReset);

    Reg#(State)    hstate <- mkReg(Idle);
    Reg#(State)    vstate <- mkReg(Idle);
    Reg#(Bit#(1))  active_video_reg <- mkReg(0);
    Reg#(Bit#(16)) vsync_count <- mkReg(0);
    Reg#(Bit#(16)) hsync_count <- mkReg(0);
    Reg#(Bit#(10)) videodata <- mkReg(0);
    Reg#(Bit#(1))  framestart_new <- mkReg(0);

    rule start_fsm if (framestart_new == 1);
        vsync_count <= 0;
        hsync_count <= 0;
        hstate <= Active;
        vstate <= Active;
    endrule

    rule sync_fsm if (framestart_new != 1);
        let hs = hstate;
        let vs = vstate;
        let hc = hsync_count;
        let vc = vsync_count;

        hc = hc + 1;
        if (hstate == FrontP && hsync_count >= host.syncgen.hfporch() - 1)
            begin
            hc = 0;
            hs = Sync;
            vc = vc + 1;
            if (vstate == Active && vsync_count >= host.syncgen.vactive() - 1)
                begin
                vc = 0;
                vs = FrontP;
                end
            if (vstate == FrontP && vsync_count >= host.syncgen.vfporch() - 1)
                begin
                vc = 0;
                vs = Sync;
                end
            if (vstate == Sync && vsync_count >= host.syncgen.vsync() - 1)
                begin
                vc = 0;
                vs = BackP;
                end
            end
        if (hstate == Sync && hsync_count >= host.syncgen.hsync() - 1)
            begin
            hc = 0;
            hs = BackP;
            end
        if (hstate == BackP && hsync_count >= host.syncgen.hbporch() - 1)
            begin
            hc = 0;
            hs = Active;
            end
        if (hstate == Active && hsync_count >= host.syncgen.hactive() - 1)
            begin
            hc = 0;
            hs = FrontP;
            end

        hstate <= hs;
        vstate <= vs;
        hsync_count <= hc;
        vsync_count <= vc;
        active_video_reg <= pack(hstate == Active && vstate == Active);
    endrule

    rule update_framestart;
	syncGearbox.deq;
        framestart_new <= syncGearbox.first[0];
    endrule

    rule update_videodata if (active_video_reg == 1);
	dataGearbox.deq;
        videodata <= dataGearbox.first[0];
    endrule

    rule receive_framestart;
	Vector#(4, Bit#(1)) in = replicate(0);
	// zero'th element shifted out first
	in[1] = sensor.get_framesync();
	syncGearbox.enq(in);
    endrule

    rule receive_data;
	    // least signifcant 10 bits shifted out first
	    Vector#(4, Bit#(10)) in = unpack(sensor.get_data());
	    dataGearbox.enq(in);
    endrule

    interface Get out;
	method ActionValue#(XsviData) get();
	    return XsviData {
		fsync: framestart_new,
		vsync: pack(vstate == Sync),
		hsync: pack(hstate == Sync),
		active_video: active_video_reg,
		video_data: videodata
	    };
	endmethod
    endinterface: out
endmodule