`timescale 1ns / 1ps `define USBHOSTSLAVE_VERSION_NUM 8'h20 //Host slave common registers `define HOST_SLAVE_CONTROL_REG 1'b0 `define HOST_SLAVE_VERSION_REG 1'b1 module hostSlaveMuxBI ( dataIn, dataOut, address, writeEn, strobe_i, busClk, usbClk, hostMode, hostSlaveMuxSel, rstFromWire, rstSyncToBusClkOut, rstSyncToUsbClkOut); input [7:0] dataIn; input address; input writeEn; input strobe_i; input busClk; input usbClk; input hostSlaveMuxSel; input rstFromWire; output [7:0] dataOut; output hostMode; output rstSyncToBusClkOut; output rstSyncToUsbClkOut; wire [7:0] dataIn; wire address; wire writeEn; wire strobe_i; wire busClk; wire usbClk; reg [7:0] dataOut; wire hostSlaveMuxSel; reg hostMode; wire rstFromWire; reg rstSyncToBusClkOut; reg rstSyncToUsbClkOut; //internal wire and regs reg [5:0] rstShift; reg rstFromBus; reg rstSyncToUsbClkFirst; //sync write demux always @(posedge busClk) begin if (rstSyncToBusClkOut == 1'b1) hostMode <= 1'b0; else begin if (writeEn == 1'b1 && hostSlaveMuxSel == 1'b1 && strobe_i == 1'b1 && address == `HOST_SLAVE_CONTROL_REG ) hostMode <= dataIn[0]; end if (writeEn == 1'b1 && hostSlaveMuxSel == 1'b1 && strobe_i == 1'b1 && address == `HOST_SLAVE_CONTROL_REG && dataIn[1] == 1'b1 ) rstFromBus <= 1'b1; else rstFromBus <= 1'b0; end // async read mux always @(address or hostMode) begin case (address) `HOST_SLAVE_CONTROL_REG: dataOut <= {7'h0, hostMode}; `HOST_SLAVE_VERSION_REG: dataOut <= `USBHOSTSLAVE_VERSION_NUM; endcase end // reset control //generate 'rstSyncToBusClk' //assuming that 'busClk' < 5 * 'usbClk'. ie 'busClk' < 240MHz always @(posedge busClk) begin if (rstFromWire == 1'b1 || rstFromBus == 1'b1) rstShift <= 6'b111111; else rstShift <= {1'b0, rstShift[5:1]}; end always @(rstShift) rstSyncToBusClkOut <= rstShift[0]; // double sync across clock domains to generate 'forceEmptySyncToWrClk' always @(posedge usbClk) begin rstSyncToUsbClkFirst <= rstSyncToBusClkOut; rstSyncToUsbClkOut <= rstSyncToUsbClkFirst; end endmodule module hostSlaveMux ( SIEPortCtrlInToSIE, SIEPortCtrlInFromHost, SIEPortCtrlInFromSlave, SIEPortDataInToSIE, SIEPortDataInFromHost, SIEPortDataInFromSlave, SIEPortWEnToSIE, SIEPortWEnFromHost, SIEPortWEnFromSlave, fullSpeedPolarityToSIE, fullSpeedPolarityFromHost, fullSpeedPolarityFromSlave, fullSpeedBitRateToSIE, fullSpeedBitRateFromHost, fullSpeedBitRateFromSlave, noActivityTimeOutEnableToSIE, noActivityTimeOutEnableFromHost, noActivityTimeOutEnableFromSlave, dataIn, dataOut, address, writeEn, strobe_i, busClk, usbClk, hostSlaveMuxSel, rstFromWire, rstSyncToBusClkOut, rstSyncToUsbClkOut ); output [7:0] SIEPortCtrlInToSIE; input [7:0] SIEPortCtrlInFromHost; input [7:0] SIEPortCtrlInFromSlave; output [7:0] SIEPortDataInToSIE; input [7:0] SIEPortDataInFromHost; input [7:0] SIEPortDataInFromSlave; output SIEPortWEnToSIE; input SIEPortWEnFromHost; input SIEPortWEnFromSlave; output fullSpeedPolarityToSIE; input fullSpeedPolarityFromHost; input fullSpeedPolarityFromSlave; output fullSpeedBitRateToSIE; input fullSpeedBitRateFromHost; input fullSpeedBitRateFromSlave; output noActivityTimeOutEnableToSIE; input noActivityTimeOutEnableFromHost; input noActivityTimeOutEnableFromSlave; //hostSlaveMuxBI input [7:0] dataIn; input address; input writeEn; input strobe_i; input busClk; input usbClk; input rstFromWire; output rstSyncToBusClkOut; output rstSyncToUsbClkOut; output [7:0] dataOut; input hostSlaveMuxSel; reg [7:0] SIEPortCtrlInToSIE; wire [7:0] SIEPortCtrlInFromHost; wire [7:0] SIEPortCtrlInFromSlave; reg [7:0] SIEPortDataInToSIE; wire [7:0] SIEPortDataInFromHost; wire [7:0] SIEPortDataInFromSlave; reg SIEPortWEnToSIE; wire SIEPortWEnFromHost; wire SIEPortWEnFromSlave; reg fullSpeedPolarityToSIE; wire fullSpeedPolarityFromHost; wire fullSpeedPolarityFromSlave; reg fullSpeedBitRateToSIE; wire fullSpeedBitRateFromHost; wire fullSpeedBitRateFromSlave; reg noActivityTimeOutEnableToSIE; wire noActivityTimeOutEnableFromHost; wire noActivityTimeOutEnableFromSlave; //hostSlaveMuxBI wire [7:0] dataIn; wire address; wire writeEn; wire strobe_i; wire busClk; wire usbClk; wire rstSyncToBusClkOut; wire rstSyncToUsbClkOut; wire rstFromWire; wire [7:0] dataOut; wire hostSlaveMuxSel; //internal wires and regs wire hostMode; always @(hostMode or SIEPortCtrlInFromHost or SIEPortCtrlInFromSlave or SIEPortDataInFromHost or SIEPortDataInFromSlave or SIEPortWEnFromHost or SIEPortWEnFromSlave or fullSpeedPolarityFromHost or fullSpeedPolarityFromSlave or fullSpeedBitRateFromHost or fullSpeedBitRateFromSlave or noActivityTimeOutEnableFromHost or noActivityTimeOutEnableFromSlave) begin if (hostMode == 1'b1) begin SIEPortCtrlInToSIE <= SIEPortCtrlInFromHost; SIEPortDataInToSIE <= SIEPortDataInFromHost; SIEPortWEnToSIE <= SIEPortWEnFromHost; fullSpeedPolarityToSIE <= fullSpeedPolarityFromHost; fullSpeedBitRateToSIE <= fullSpeedBitRateFromHost; noActivityTimeOutEnableToSIE <= noActivityTimeOutEnableFromHost; end else begin SIEPortCtrlInToSIE <= SIEPortCtrlInFromSlave; SIEPortDataInToSIE <= SIEPortDataInFromSlave; SIEPortWEnToSIE <= SIEPortWEnFromSlave; fullSpeedPolarityToSIE <= fullSpeedPolarityFromSlave; fullSpeedBitRateToSIE <= fullSpeedBitRateFromSlave; noActivityTimeOutEnableToSIE <= noActivityTimeOutEnableFromSlave; end end hostSlaveMuxBI u_hostSlaveMuxBI ( .dataIn(dataIn), .dataOut(dataOut), .address(address), .writeEn(writeEn), .strobe_i(strobe_i), .busClk(busClk), .usbClk(usbClk), .hostMode(hostMode), .hostSlaveMuxSel(hostSlaveMuxSel), .rstFromWire(rstFromWire), .rstSyncToBusClkOut(rstSyncToBusClkOut), .rstSyncToUsbClkOut(rstSyncToUsbClkOut) ); endmodule