URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2/rtl
- from Rev 403 to Rev 408
- ↔ Reverse comparison
Rev 403 → Rev 408
/verilog/eth/eth.v
0,0 → 1,979
////////////////////////////////////////////////////////////////////// |
//// //// |
//// eth.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://www.opencores.org/projects/ethmac/ //// |
//// //// |
//// Author(s): //// |
//// - Igor Mohor (igorM@opencores.org) //// |
//// //// |
//// All additional information is available in the Readme.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001, 2002 Authors //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.51 2005/02/21 11:13:17 igorm |
// Defer indication fixed. |
// |
// Revision 1.50 2004/04/26 15:26:23 igorm |
// - Bug connected to the TX_BD_NUM_Wr signal fixed (bug came in with the |
// previous update of the core. |
// - TxBDAddress is set to 0 after the TX is enabled in the MODER register. |
// - RxBDAddress is set to r_TxBDNum<<1 after the RX is enabled in the MODER |
// register. (thanks to Mathias and Torbjorn) |
// - Multicast reception was fixed. Thanks to Ulrich Gries |
// |
// Revision 1.49 2003/11/12 18:24:59 tadejm |
// WISHBONE slave changed and tested from only 32-bit accesss to byte access. |
// |
// Revision 1.48 2003/10/17 07:46:16 markom |
// mbist signals updated according to newest convention |
// |
// Revision 1.47 2003/10/06 15:43:45 knguyen |
// Update RxEnSync only when mrxdv_pad_i is inactive (LOW). |
// |
// Revision 1.46 2003/01/30 13:30:22 tadejm |
// Defer indication changed. |
// |
// Revision 1.45 2003/01/22 13:49:26 tadejm |
// When control packets were received, they were ignored in some cases. |
// |
// Revision 1.44 2003/01/21 12:09:40 mohor |
// When receiving normal data frame and RxFlow control was switched on, RXB |
// interrupt was not set. |
// |
// Revision 1.43 2002/11/22 01:57:06 mohor |
// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort |
// synchronized. |
// |
// Revision 1.42 2002/11/21 00:09:19 mohor |
// TPauseRq synchronized to tx_clk. |
// |
// Revision 1.41 2002/11/19 18:13:49 mohor |
// r_MiiMRst is not used for resetting the MIIM module. wb_rst used instead. |
// |
// Revision 1.40 2002/11/19 17:34:25 mohor |
// AddressMiss status is connecting to the Rx BD. AddressMiss is identifying |
// that a frame was received because of the promiscous mode. |
// |
// Revision 1.39 2002/11/18 17:31:55 mohor |
// wb_rst_i is used for MIIM reset. |
// |
// Revision 1.38 2002/11/14 18:37:20 mohor |
// r_Rst signal does not reset any module any more and is removed from the design. |
// |
// Revision 1.37 2002/11/13 22:25:36 tadejm |
// All modules are reset with wb_rst instead of the r_Rst. Exception is MII module. |
// |
// Revision 1.36 2002/10/18 17:04:20 tadejm |
// Changed BIST scan signals. |
// |
// Revision 1.35 2002/10/11 13:36:58 mohor |
// Typo error fixed. (When using Bist) |
// |
// Revision 1.34 2002/10/10 16:49:50 mohor |
// Signals for WISHBONE B3 compliant interface added. |
// |
// Revision 1.33 2002/10/10 16:29:30 mohor |
// BIST added. |
// |
// Revision 1.32 2002/09/20 17:12:58 mohor |
// CsMiss added. When address between 0x800 and 0xfff is accessed within |
// Ethernet Core, error acknowledge is generated. |
// |
// Revision 1.31 2002/09/12 14:50:17 mohor |
// CarrierSenseLost bug fixed when operating in full duplex mode. |
// |
// Revision 1.30 2002/09/10 10:35:23 mohor |
// Ethernet debug registers removed. |
// |
// Revision 1.29 2002/09/09 13:03:13 mohor |
// Error acknowledge is generated when accessing BDs and RST bit in the |
// MODER register (r_Rst) is set. |
// |
// Revision 1.28 2002/09/04 18:44:10 mohor |
// Signals related to the control frames connected. Debug registers reg1, 2, 3, 4 |
// connected. |
// |
// Revision 1.27 2002/07/25 18:15:37 mohor |
// RxAbort changed. Packets received with MRxErr (from PHY) are also |
// aborted. |
// |
// Revision 1.26 2002/07/17 18:51:50 mohor |
// EXTERNAL_DMA removed. External DMA not supported. |
// |
// Revision 1.25 2002/05/03 10:15:50 mohor |
// Outputs registered. Reset changed for eth_wishbone module. |
// |
// Revision 1.24 2002/04/22 14:15:42 mohor |
// Wishbone signals are registered when ETH_REGISTERED_OUTPUTS is |
// selected in eth_defines.v |
// |
// Revision 1.23 2002/03/25 13:33:53 mohor |
// md_padoen_o changed to md_padoe_o. Signal was always active high, just |
// name was incorrect. |
// |
// Revision 1.22 2002/02/26 16:59:54 mohor |
// Small fixes for external/internal DMA missmatches. |
// |
// Revision 1.21 2002/02/26 16:21:00 mohor |
// Interrupts changed in the top file |
// |
// Revision 1.20 2002/02/18 10:40:17 mohor |
// Small fixes. |
// |
// Revision 1.19 2002/02/16 14:03:44 mohor |
// Registered trimmed. Unused registers removed. |
// |
// Revision 1.18 2002/02/16 13:06:33 mohor |
// EXTERNAL_DMA used instead of WISHBONE_DMA. |
// |
// Revision 1.17 2002/02/16 07:15:27 mohor |
// Testbench fixed, code simplified, unused signals removed. |
// |
// Revision 1.16 2002/02/15 13:49:39 mohor |
// RxAbort is connected differently. |
// |
// Revision 1.15 2002/02/15 11:38:26 mohor |
// Changes that were lost when updating from 1.11 to 1.14 fixed. |
// |
// Revision 1.14 2002/02/14 20:19:11 billditt |
// Modified for Address Checking, |
// addition of eth_addrcheck.v |
// |
// Revision 1.13 2002/02/12 17:03:03 mohor |
// HASH0 and HASH1 registers added. Registers address width was |
// changed to 8 bits. |
// |
// Revision 1.12 2002/02/11 09:18:22 mohor |
// Tx status is written back to the BD. |
// |
// Revision 1.11 2002/02/08 16:21:54 mohor |
// Rx status is written back to the BD. |
// |
// Revision 1.10 2002/02/06 14:10:21 mohor |
// non-DMA host interface added. Select the right configutation in eth_defines. |
// |
// Revision 1.9 2002/01/23 10:28:16 mohor |
// Link in the header changed. |
// |
// Revision 1.8 2001/12/05 15:00:16 mohor |
// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors |
// instead of the number of RX descriptors). |
// |
// Revision 1.7 2001/12/05 10:45:59 mohor |
// ETH_RX_BD_ADR register deleted. ETH_RX_BD_NUM is used instead. |
// |
// Revision 1.6 2001/10/19 11:24:29 mohor |
// Number of addresses (wb_adr_i) minimized. |
// |
// Revision 1.5 2001/10/19 08:43:51 mohor |
// eth_timescale.v changed to timescale.v This is done because of the |
// simulation of the few cores in a one joined project. |
// |
// Revision 1.4 2001/10/18 12:07:11 mohor |
// Status signals changed, Adress decoding changed, interrupt controller |
// added. |
// |
// Revision 1.3 2001/09/24 15:02:56 mohor |
// Defines changed (All precede with ETH_). Small changes because some |
// tools generate warnings when two operands are together. Synchronization |
// between two clocks domains in eth_wishbonedma.v is changed (due to ASIC |
// demands). |
// |
// Revision 1.2 2001/08/15 14:03:59 mohor |
// Signal names changed on the top level for easier pad insertion (ASIC). |
// |
// Revision 1.1 2001/08/06 14:44:29 mohor |
// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). |
// Include files fixed to contain no path. |
// File names and module names changed ta have a eth_ prologue in the name. |
// File eth_timescale.v is used to define timescale |
// All pin names on the top module are changed to contain _I, _O or _OE at the end. |
// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O |
// and Mdo_OE. The bidirectional signal must be created on the top level. This |
// is done due to the ASIC tools. |
// |
// Revision 1.2 2001/08/02 09:25:31 mohor |
// Unconnected signals are now connected. |
// |
// Revision 1.1 2001/07/30 21:23:42 mohor |
// Directory structure changed. Files checked and joind together. |
// |
// |
// |
// |
|
|
`include "eth_defines.v" |
`include "timescale.v" |
|
|
module eth // renamed jb |
( |
// WISHBONE common |
wb_clk_i, wb_rst_i, wb_dat_i, wb_dat_o, |
|
// WISHBONE slave |
wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i, wb_stb_i, wb_ack_o, wb_err_o, |
|
// WISHBONE master |
m_wb_adr_o, m_wb_sel_o, m_wb_we_o, |
m_wb_dat_o, m_wb_dat_i, m_wb_cyc_o, |
m_wb_stb_o, m_wb_ack_i, m_wb_err_i, |
|
`ifdef ETH_WISHBONE_B3 |
m_wb_cti_o, m_wb_bte_o, |
`endif |
|
//TX |
mtx_clk_pad_i, mtxd_pad_o, mtxen_pad_o, mtxerr_pad_o, |
|
//RX |
mrx_clk_pad_i, mrxd_pad_i, mrxdv_pad_i, mrxerr_pad_i, mcoll_pad_i, mcrs_pad_i, |
|
// MIIM |
mdc_pad_o, md_pad_i, md_pad_o, md_padoe_o, |
|
int_o |
|
// Bist |
`ifdef ETH_BIST |
, |
// debug chain signals |
mbist_si_i, // bist scan serial in |
mbist_so_o, // bist scan serial out |
mbist_ctrl_i // bist chain shift control |
`endif |
|
); |
|
|
parameter Tp = 1; |
|
|
// WISHBONE common |
input wb_clk_i; // WISHBONE clock |
input wb_rst_i; // WISHBONE reset |
input [31:0] wb_dat_i; // WISHBONE data input |
output [31:0] wb_dat_o; // WISHBONE data output |
output wb_err_o; // WISHBONE error output |
|
// WISHBONE slave |
input [11:2] wb_adr_i; // WISHBONE address input |
input [3:0] wb_sel_i; // WISHBONE byte select input |
input wb_we_i; // WISHBONE write enable input |
input wb_cyc_i; // WISHBONE cycle input |
input wb_stb_i; // WISHBONE strobe input |
output wb_ack_o; // WISHBONE acknowledge output |
|
// WISHBONE master |
output [31:0] m_wb_adr_o; |
output [3:0] m_wb_sel_o; |
output m_wb_we_o; |
input [31:0] m_wb_dat_i; |
output [31:0] m_wb_dat_o; |
output m_wb_cyc_o; |
output m_wb_stb_o; |
input m_wb_ack_i; |
input m_wb_err_i; |
|
wire [29:0] m_wb_adr_tmp; |
|
`ifdef ETH_WISHBONE_B3 |
output [2:0] m_wb_cti_o; // Cycle Type Identifier |
output [1:0] m_wb_bte_o; // Burst Type Extension |
`endif |
|
// Tx |
input mtx_clk_pad_i; // Transmit clock (from PHY) |
output [3:0] mtxd_pad_o; // Transmit nibble (to PHY) |
output mtxen_pad_o; // Transmit enable (to PHY) |
output mtxerr_pad_o; // Transmit error (to PHY) |
|
// Rx |
input mrx_clk_pad_i; // Receive clock (from PHY) |
input [3:0] mrxd_pad_i; // Receive nibble (from PHY) |
input mrxdv_pad_i; // Receive data valid (from PHY) |
input mrxerr_pad_i; // Receive data error (from PHY) |
|
// Common Tx and Rx |
input mcoll_pad_i; // Collision (from PHY) |
input mcrs_pad_i; // Carrier sense (from PHY) |
|
// MII Management interface |
input md_pad_i; // MII data input (from I/O cell) |
output mdc_pad_o; // MII Management data clock (to PHY) |
output md_pad_o; // MII data output (to I/O cell) |
output md_padoe_o; // MII data output enable (to I/O cell) |
|
output int_o; // Interrupt output |
|
// Bist |
`ifdef ETH_BIST |
input mbist_si_i; // bist scan serial in |
output mbist_so_o; // bist scan serial out |
input [`ETH_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control |
`endif |
|
`ifdef WISHBONE_DEBUG |
wire [31:0] wb_dbg_dat0; |
`endif |
|
|
wire [7:0] r_ClkDiv; |
wire r_MiiNoPre; |
wire [15:0] r_CtrlData; |
wire [4:0] r_FIAD; |
wire [4:0] r_RGAD; |
wire r_WCtrlData; |
wire r_RStat; |
wire r_ScanStat; |
wire NValid_stat; |
wire Busy_stat; |
wire LinkFail; |
wire [15:0] Prsd; // Read Status Data (data read from the PHY) |
wire WCtrlDataStart; |
wire RStatStart; |
wire UpdateMIIRX_DATAReg; |
|
wire TxStartFrm; |
wire TxEndFrm; |
wire TxUsedData; |
wire [7:0] TxData; |
wire TxRetry; |
wire TxAbort; |
wire TxUnderRun; |
wire TxDone; |
|
|
reg WillSendControlFrame_sync1; |
reg WillSendControlFrame_sync2; |
reg WillSendControlFrame_sync3; |
reg RstTxPauseRq; |
|
reg TxPauseRq_sync1; |
reg TxPauseRq_sync2; |
reg TxPauseRq_sync3; |
reg TPauseRq; |
|
|
// Connecting Miim module |
eth_miim miim1 |
( |
.Clk(wb_clk_i), .Reset(wb_rst_i), .Divider(r_ClkDiv), |
.NoPre(r_MiiNoPre), .CtrlData(r_CtrlData), .Rgad(r_RGAD), |
.Fiad(r_FIAD), .WCtrlData(r_WCtrlData), .RStat(r_RStat), |
.ScanStat(r_ScanStat), .Mdi(md_pad_i), .Mdo(md_pad_o), |
.MdoEn(md_padoe_o), .Mdc(mdc_pad_o), .Busy(Busy_stat), |
.Prsd(Prsd), .LinkFail(LinkFail), .Nvalid(NValid_stat), |
.WCtrlDataStart(WCtrlDataStart), .RStatStart(RStatStart), .UpdateMIIRX_DATAReg(UpdateMIIRX_DATAReg) |
); |
|
|
|
|
wire [3:0] RegCs; // Connected to registers |
wire [31:0] RegDataOut; // Multiplexed to wb_dat_o |
wire r_RecSmall; // Receive small frames |
wire r_LoopBck; // Loopback |
wire r_TxEn; // Tx Enable |
wire r_RxEn; // Rx Enable |
|
wire MRxDV_Lb; // Muxed MII receive data valid |
wire MRxErr_Lb; // Muxed MII Receive Error |
wire [3:0] MRxD_Lb; // Muxed MII Receive Data |
wire Transmitting; // Indication that TxEthMAC is transmitting |
wire r_HugEn; // Huge packet enable |
wire r_DlyCrcEn; // Delayed CRC enabled |
wire [15:0] r_MaxFL; // Maximum frame length |
|
wire [15:0] r_MinFL; // Minimum frame length |
wire ShortFrame; |
wire DribbleNibble; // Extra nibble received |
wire ReceivedPacketTooBig; // Received packet is too big |
wire [47:0] r_MAC; // MAC address |
wire LoadRxStatus; // Rx status was loaded |
wire [31:0] r_HASH0; // HASH table, lower 4 bytes |
wire [31:0] r_HASH1; // HASH table, upper 4 bytes |
wire [7:0] r_TxBDNum; // Receive buffer descriptor number |
wire [6:0] r_IPGT; // |
wire [6:0] r_IPGR1; // |
wire [6:0] r_IPGR2; // |
wire [5:0] r_CollValid; // |
wire [15:0] r_TxPauseTV; // Transmit PAUSE value |
wire r_TxPauseRq; // Transmit PAUSE request |
|
wire [3:0] r_MaxRet; // |
wire r_NoBckof; // |
wire r_ExDfrEn; // |
wire r_TxFlow; // Tx flow control enable |
wire r_IFG; // Minimum interframe gap for incoming packets |
|
wire TxB_IRQ; // Interrupt Tx Buffer |
wire TxE_IRQ; // Interrupt Tx Error |
wire RxB_IRQ; // Interrupt Rx Buffer |
wire RxE_IRQ; // Interrupt Rx Error |
wire Busy_IRQ; // Interrupt Busy (lack of buffers) |
|
//wire DWord; |
wire ByteSelected; |
wire BDAck; |
wire [31:0] BD_WB_DAT_O; // wb_dat_o that comes from the Wishbone module (for buffer descriptors read/write) |
wire [3:0] BDCs; // Buffer descriptor CS |
wire CsMiss; // When access to the address between 0x800 and 0xfff occurs, acknowledge is set |
// but data is not valid. |
wire r_Pad; |
wire r_CrcEn; |
wire r_FullD; |
wire r_Pro; |
wire r_Bro; |
wire r_NoPre; |
wire r_RxFlow; |
wire r_PassAll; |
wire TxCtrlEndFrm; |
wire StartTxDone; |
wire SetPauseTimer; |
wire TxUsedDataIn; |
wire TxDoneIn; |
wire TxAbortIn; |
wire PerPacketPad; |
wire PadOut; |
wire PerPacketCrcEn; |
wire CrcEnOut; |
wire TxStartFrmOut; |
wire TxEndFrmOut; |
wire ReceivedPauseFrm; |
wire ControlFrmAddressOK; |
wire RxStatusWriteLatched_sync2; |
wire LateCollision; |
wire DeferIndication; |
wire LateCollLatched; |
wire DeferLatched; |
wire RstDeferLatched; |
wire CarrierSenseLost; |
|
wire temp_wb_ack_o; |
wire [31:0] temp_wb_dat_o; |
wire temp_wb_err_o; |
|
`ifdef ETH_REGISTERED_OUTPUTS |
reg temp_wb_ack_o_reg; |
reg [31:0] temp_wb_dat_o_reg; |
reg temp_wb_err_o_reg; |
`endif |
|
//assign DWord = &wb_sel_i; |
assign ByteSelected = |wb_sel_i; |
assign RegCs[3] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & ~wb_adr_i[10] & wb_sel_i[3]; // 0x0 - 0x3FF |
assign RegCs[2] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & ~wb_adr_i[10] & wb_sel_i[2]; // 0x0 - 0x3FF |
assign RegCs[1] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & ~wb_adr_i[10] & wb_sel_i[1]; // 0x0 - 0x3FF |
assign RegCs[0] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & ~wb_adr_i[10] & wb_sel_i[0]; // 0x0 - 0x3FF |
assign BDCs[3] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & wb_adr_i[10] & wb_sel_i[3]; // 0x400 - 0x7FF |
assign BDCs[2] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & wb_adr_i[10] & wb_sel_i[2]; // 0x400 - 0x7FF |
assign BDCs[1] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & wb_adr_i[10] & wb_sel_i[1]; // 0x400 - 0x7FF |
assign BDCs[0] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & wb_adr_i[10] & wb_sel_i[0]; // 0x400 - 0x7FF |
assign CsMiss = wb_stb_i & wb_cyc_i & ByteSelected & wb_adr_i[11]; // 0x800 - 0xfFF |
assign temp_wb_dat_o = ((|RegCs) & ~wb_we_i)? RegDataOut : BD_WB_DAT_O; |
assign temp_wb_err_o = wb_stb_i & wb_cyc_i & (~ByteSelected | CsMiss); |
|
`ifdef ETH_REGISTERED_OUTPUTS |
assign wb_ack_o = temp_wb_ack_o_reg; |
assign wb_dat_o[31:0] = temp_wb_dat_o_reg; |
assign wb_err_o = temp_wb_err_o_reg; |
`else |
assign wb_ack_o = temp_wb_ack_o; |
assign wb_dat_o[31:0] = temp_wb_dat_o; |
assign wb_err_o = temp_wb_err_o; |
`endif |
|
`ifdef ETH_AVALON_BUS |
// As Avalon has no corresponding "error" signal, I (erroneously) will |
// send an ack to Avalon, even when accessing undefined memory. This |
// is a grey area in Avalon vs. Wishbone specs: My understanding |
// is that Avalon expects all memory addressable by the addr bus feeding |
// a slave to be, at the very minimum, readable. |
assign temp_wb_ack_o = (|RegCs) | BDAck | CsMiss; |
`else // WISHBONE |
assign temp_wb_ack_o = (|RegCs) | BDAck; |
`endif |
|
`ifdef ETH_REGISTERED_OUTPUTS |
always @ (posedge wb_clk_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
begin |
temp_wb_ack_o_reg <= 1'b0; |
temp_wb_dat_o_reg <= 32'h0; |
temp_wb_err_o_reg <= 1'b0; |
end |
else |
begin |
temp_wb_ack_o_reg <= temp_wb_ack_o & ~temp_wb_ack_o_reg; |
temp_wb_dat_o_reg <= temp_wb_dat_o; |
temp_wb_err_o_reg <= temp_wb_err_o & ~temp_wb_err_o_reg; |
end |
end |
`endif |
|
|
// Connecting Ethernet registers |
eth_registers ethreg1 |
( |
.DataIn(wb_dat_i), .Address(wb_adr_i[9:2]), .Rw(wb_we_i), |
.Cs(RegCs), .Clk(wb_clk_i), .Reset(wb_rst_i), |
.DataOut(RegDataOut), .r_RecSmall(r_RecSmall), |
.r_Pad(r_Pad), .r_HugEn(r_HugEn), .r_CrcEn(r_CrcEn), |
.r_DlyCrcEn(r_DlyCrcEn), .r_FullD(r_FullD), |
.r_ExDfrEn(r_ExDfrEn), .r_NoBckof(r_NoBckof), .r_LoopBck(r_LoopBck), |
.r_IFG(r_IFG), .r_Pro(r_Pro), .r_Iam(), |
.r_Bro(r_Bro), .r_NoPre(r_NoPre), .r_TxEn(r_TxEn), |
.r_RxEn(r_RxEn), .Busy_IRQ(Busy_IRQ), .RxE_IRQ(RxE_IRQ), |
.RxB_IRQ(RxB_IRQ), .TxE_IRQ(TxE_IRQ), .TxB_IRQ(TxB_IRQ), |
.r_IPGT(r_IPGT), |
.r_IPGR1(r_IPGR1), .r_IPGR2(r_IPGR2), .r_MinFL(r_MinFL), |
.r_MaxFL(r_MaxFL), .r_MaxRet(r_MaxRet), .r_CollValid(r_CollValid), |
.r_TxFlow(r_TxFlow), .r_RxFlow(r_RxFlow), .r_PassAll(r_PassAll), |
.r_MiiNoPre(r_MiiNoPre), .r_ClkDiv(r_ClkDiv), |
.r_WCtrlData(r_WCtrlData), .r_RStat(r_RStat), .r_ScanStat(r_ScanStat), |
.r_RGAD(r_RGAD), .r_FIAD(r_FIAD), .r_CtrlData(r_CtrlData), |
.NValid_stat(NValid_stat), .Busy_stat(Busy_stat), |
.LinkFail(LinkFail), .r_MAC(r_MAC), .WCtrlDataStart(WCtrlDataStart), |
.RStatStart(RStatStart), .UpdateMIIRX_DATAReg(UpdateMIIRX_DATAReg), .Prsd(Prsd), |
.r_TxBDNum(r_TxBDNum), .int_o(int_o), |
.r_HASH0(r_HASH0), .r_HASH1(r_HASH1), .r_TxPauseRq(r_TxPauseRq), |
.r_TxPauseTV(r_TxPauseTV), .RstTxPauseRq(RstTxPauseRq), .TxCtrlEndFrm(TxCtrlEndFrm), |
.StartTxDone(StartTxDone), .TxClk(mtx_clk_pad_i), .RxClk(mrx_clk_pad_i), |
.dbg_dat(wb_dbg_dat0), |
.SetPauseTimer(SetPauseTimer) |
|
); |
|
|
|
wire [7:0] RxData; |
wire RxValid; |
wire RxStartFrm; |
wire RxEndFrm; |
wire RxAbort; |
|
wire WillTransmit; // Will transmit (to RxEthMAC) |
wire ResetCollision; // Reset Collision (for synchronizing collision) |
wire [7:0] TxDataOut; // Transmit Packet Data (to TxEthMAC) |
wire WillSendControlFrame; |
wire ReceiveEnd; |
wire ReceivedPacketGood; |
wire ReceivedLengthOK; |
wire InvalidSymbol; |
wire LatchedCrcError; |
wire RxLateCollision; |
wire [3:0] RetryCntLatched; |
wire [3:0] RetryCnt; |
wire StartTxAbort; |
wire MaxCollisionOccured; |
wire RetryLimit; |
wire StatePreamble; |
wire [1:0] StateData; |
|
// Connecting MACControl |
eth_maccontrol maccontrol1 |
( |
.MTxClk(mtx_clk_pad_i), .TPauseRq(TPauseRq), |
.TxPauseTV(r_TxPauseTV), .TxDataIn(TxData), |
.TxStartFrmIn(TxStartFrm), .TxEndFrmIn(TxEndFrm), |
.TxUsedDataIn(TxUsedDataIn), .TxDoneIn(TxDoneIn), |
.TxAbortIn(TxAbortIn), .MRxClk(mrx_clk_pad_i), |
.RxData(RxData), .RxValid(RxValid), |
.RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), |
.ReceiveEnd(ReceiveEnd), .ReceivedPacketGood(ReceivedPacketGood), |
.TxFlow(r_TxFlow), |
.RxFlow(r_RxFlow), .DlyCrcEn(r_DlyCrcEn), |
.MAC(r_MAC), .PadIn(r_Pad | PerPacketPad), |
.PadOut(PadOut), .CrcEnIn(r_CrcEn | PerPacketCrcEn), |
.CrcEnOut(CrcEnOut), .TxReset(wb_rst_i), |
.RxReset(wb_rst_i), .ReceivedLengthOK(ReceivedLengthOK), |
.TxDataOut(TxDataOut), .TxStartFrmOut(TxStartFrmOut), |
.TxEndFrmOut(TxEndFrmOut), .TxUsedDataOut(TxUsedData), |
.TxDoneOut(TxDone), .TxAbortOut(TxAbort), |
.WillSendControlFrame(WillSendControlFrame), .TxCtrlEndFrm(TxCtrlEndFrm), |
.ReceivedPauseFrm(ReceivedPauseFrm), .ControlFrmAddressOK(ControlFrmAddressOK), |
.SetPauseTimer(SetPauseTimer), |
.RxStatusWriteLatched_sync2(RxStatusWriteLatched_sync2), .r_PassAll(r_PassAll) |
); |
|
|
|
wire TxCarrierSense; // Synchronized CarrierSense (to Tx clock) |
wire Collision; // Synchronized Collision |
|
reg CarrierSense_Tx1; |
reg CarrierSense_Tx2; |
reg Collision_Tx1; |
reg Collision_Tx2; |
|
reg RxEnSync; // Synchronized Receive Enable |
reg WillTransmit_q; |
reg WillTransmit_q2; |
|
|
|
// Muxed MII receive data valid |
assign MRxDV_Lb = r_LoopBck? mtxen_pad_o : mrxdv_pad_i & RxEnSync; |
|
// Muxed MII Receive Error |
assign MRxErr_Lb = r_LoopBck? mtxerr_pad_o : mrxerr_pad_i & RxEnSync; |
|
// Muxed MII Receive Data |
assign MRxD_Lb[3:0] = r_LoopBck? mtxd_pad_o[3:0] : mrxd_pad_i[3:0]; |
|
|
|
// Connecting TxEthMAC |
eth_txethmac txethmac1 |
( |
.MTxClk(mtx_clk_pad_i), .Reset(wb_rst_i), .CarrierSense(TxCarrierSense), |
.Collision(Collision), .TxData(TxDataOut), .TxStartFrm(TxStartFrmOut), |
.TxUnderRun(TxUnderRun), .TxEndFrm(TxEndFrmOut), .Pad(PadOut), |
.MinFL(r_MinFL), .CrcEn(CrcEnOut), .FullD(r_FullD), |
.HugEn(r_HugEn), .DlyCrcEn(r_DlyCrcEn), .IPGT(r_IPGT), |
.IPGR1(r_IPGR1), .IPGR2(r_IPGR2), .CollValid(r_CollValid), |
.MaxRet(r_MaxRet), .NoBckof(r_NoBckof), .ExDfrEn(r_ExDfrEn), |
.MaxFL(r_MaxFL), .MTxEn(mtxen_pad_o), .MTxD(mtxd_pad_o), |
.MTxErr(mtxerr_pad_o), .TxUsedData(TxUsedDataIn), .TxDone(TxDoneIn), |
.TxRetry(TxRetry), .TxAbort(TxAbortIn), .WillTransmit(WillTransmit), |
.ResetCollision(ResetCollision), .RetryCnt(RetryCnt), .StartTxDone(StartTxDone), |
.StartTxAbort(StartTxAbort), .MaxCollisionOccured(MaxCollisionOccured), .LateCollision(LateCollision), |
.DeferIndication(DeferIndication), .StatePreamble(StatePreamble), .StateData(StateData) |
); |
|
|
|
|
wire [15:0] RxByteCnt; |
wire RxByteCntEq0; |
wire RxByteCntGreat2; |
wire RxByteCntMaxFrame; |
wire RxCrcError; |
wire RxStateIdle; |
wire RxStatePreamble; |
wire RxStateSFD; |
wire [1:0] RxStateData; |
wire AddressMiss; |
|
|
|
// Connecting RxEthMAC |
eth_rxethmac rxethmac1 |
( |
.MRxClk(mrx_clk_pad_i), .MRxDV(MRxDV_Lb), .MRxD(MRxD_Lb), |
.Transmitting(Transmitting), .HugEn(r_HugEn), .DlyCrcEn(r_DlyCrcEn), |
.MaxFL(r_MaxFL), .r_IFG(r_IFG), .Reset(wb_rst_i), |
.RxData(RxData), .RxValid(RxValid), .RxStartFrm(RxStartFrm), |
.RxEndFrm(RxEndFrm), .ByteCnt(RxByteCnt), |
.ByteCntEq0(RxByteCntEq0), .ByteCntGreat2(RxByteCntGreat2), .ByteCntMaxFrame(RxByteCntMaxFrame), |
.CrcError(RxCrcError), .StateIdle(RxStateIdle), .StatePreamble(RxStatePreamble), |
.StateSFD(RxStateSFD), .StateData(RxStateData), |
.MAC(r_MAC), .r_Pro(r_Pro), .r_Bro(r_Bro), |
.r_HASH0(r_HASH0), .r_HASH1(r_HASH1), .RxAbort(RxAbort), |
.AddressMiss(AddressMiss), .PassAll(r_PassAll), .ControlFrmAddressOK(ControlFrmAddressOK) |
); |
|
|
// MII Carrier Sense Synchronization |
always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
begin |
CarrierSense_Tx1 <= 1'b0; |
CarrierSense_Tx2 <= 1'b0; |
end |
else |
begin |
CarrierSense_Tx1 <= mcrs_pad_i; |
CarrierSense_Tx2 <= CarrierSense_Tx1; |
end |
end |
|
assign TxCarrierSense = ~r_FullD & CarrierSense_Tx2; |
|
|
// MII Collision Synchronization |
always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
begin |
Collision_Tx1 <= 1'b0; |
Collision_Tx2 <= 1'b0; |
end |
else |
begin |
Collision_Tx1 <= mcoll_pad_i; |
if(ResetCollision) |
Collision_Tx2 <= 1'b0; |
else |
if(Collision_Tx1) |
Collision_Tx2 <= 1'b1; |
end |
end |
|
|
// Synchronized Collision |
assign Collision = ~r_FullD & Collision_Tx2; |
|
|
|
// Delayed WillTransmit |
always @ (posedge mrx_clk_pad_i) |
begin |
WillTransmit_q <= WillTransmit; |
WillTransmit_q2 <= WillTransmit_q; |
end |
|
|
assign Transmitting = ~r_FullD & WillTransmit_q2; |
|
|
|
// Synchronized Receive Enable |
always @ (posedge mrx_clk_pad_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
RxEnSync <= 1'b0; |
else |
if(~mrxdv_pad_i) |
RxEnSync <= r_RxEn; |
end |
|
|
|
// Synchronizing WillSendControlFrame to WB_CLK; |
always @ (posedge wb_clk_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
WillSendControlFrame_sync1 <= 1'b0; |
else |
WillSendControlFrame_sync1 <= WillSendControlFrame; |
end |
|
always @ (posedge wb_clk_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
WillSendControlFrame_sync2 <= 1'b0; |
else |
WillSendControlFrame_sync2 <= WillSendControlFrame_sync1; |
end |
|
always @ (posedge wb_clk_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
WillSendControlFrame_sync3 <= 1'b0; |
else |
WillSendControlFrame_sync3 <= WillSendControlFrame_sync2; |
end |
|
always @ (posedge wb_clk_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
RstTxPauseRq <= 1'b0; |
else |
RstTxPauseRq <= WillSendControlFrame_sync2 & ~WillSendControlFrame_sync3; |
end |
|
|
|
|
// TX Pause request Synchronization |
always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
begin |
TxPauseRq_sync1 <= 1'b0; |
TxPauseRq_sync2 <= 1'b0; |
TxPauseRq_sync3 <= 1'b0; |
end |
else |
begin |
TxPauseRq_sync1 <= (r_TxPauseRq & r_TxFlow); |
TxPauseRq_sync2 <= TxPauseRq_sync1; |
TxPauseRq_sync3 <= TxPauseRq_sync2; |
end |
end |
|
|
always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
TPauseRq <= 1'b0; |
else |
TPauseRq <= TxPauseRq_sync2 & (~TxPauseRq_sync3); |
end |
|
|
wire LatchedMRxErr; |
reg RxAbort_latch; |
reg RxAbort_sync1; |
reg RxAbort_wb; |
reg RxAbortRst_sync1; |
reg RxAbortRst; |
|
// Synchronizing RxAbort to the WISHBONE clock |
always @ (posedge mrx_clk_pad_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
RxAbort_latch <= 1'b0; |
else if(RxAbort | (ShortFrame & ~r_RecSmall) | LatchedMRxErr & ~InvalidSymbol | (ReceivedPauseFrm & (~r_PassAll))) |
RxAbort_latch <= 1'b1; |
else if(RxAbortRst) |
RxAbort_latch <= 1'b0; |
end |
|
always @ (posedge wb_clk_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
begin |
RxAbort_sync1 <= 1'b0; |
RxAbort_wb <= 1'b0; |
RxAbort_wb <= 1'b0; |
end |
else |
begin |
RxAbort_sync1 <= RxAbort_latch; |
RxAbort_wb <= RxAbort_sync1; |
end |
end |
|
always @ (posedge mrx_clk_pad_i or posedge wb_rst_i) |
begin |
if(wb_rst_i) |
begin |
RxAbortRst_sync1 <= 1'b0; |
RxAbortRst <= 1'b0; |
end |
else |
begin |
RxAbortRst_sync1 <= RxAbort_wb; |
RxAbortRst <= RxAbortRst_sync1; |
end |
end |
|
|
|
// Connecting Wishbone module |
eth_wishbone wishbone |
( |
.WB_CLK_I(wb_clk_i), .WB_DAT_I(wb_dat_i), |
.WB_DAT_O(BD_WB_DAT_O), |
|
// WISHBONE slave |
.WB_ADR_I(wb_adr_i[9:2]), .WB_WE_I(wb_we_i), |
.BDCs(BDCs), .WB_ACK_O(BDAck), |
|
.Reset(wb_rst_i), |
|
// WISHBONE master |
.m_wb_adr_o(m_wb_adr_tmp), .m_wb_sel_o(m_wb_sel_o), .m_wb_we_o(m_wb_we_o), |
.m_wb_dat_i(m_wb_dat_i), .m_wb_dat_o(m_wb_dat_o), .m_wb_cyc_o(m_wb_cyc_o), |
.m_wb_stb_o(m_wb_stb_o), .m_wb_ack_i(m_wb_ack_i), .m_wb_err_i(m_wb_err_i), |
|
`ifdef ETH_WISHBONE_B3 |
.m_wb_cti_o(m_wb_cti_o), .m_wb_bte_o(m_wb_bte_o), |
`endif |
|
|
//TX |
.MTxClk(mtx_clk_pad_i), .TxStartFrm(TxStartFrm), .TxEndFrm(TxEndFrm), |
.TxUsedData(TxUsedData), .TxData(TxData), |
.TxRetry(TxRetry), .TxAbort(TxAbort), .TxUnderRun(TxUnderRun), |
.TxDone(TxDone), |
.PerPacketCrcEn(PerPacketCrcEn), .PerPacketPad(PerPacketPad), |
|
// Register |
.r_TxEn(r_TxEn), .r_RxEn(r_RxEn), .r_TxBDNum(r_TxBDNum), |
.r_RxFlow(r_RxFlow), .r_PassAll(r_PassAll), |
|
//RX |
.MRxClk(mrx_clk_pad_i), .RxData(RxData), .RxValid(RxValid), |
.RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), |
.Busy_IRQ(Busy_IRQ), .RxE_IRQ(RxE_IRQ), .RxB_IRQ(RxB_IRQ), |
.TxE_IRQ(TxE_IRQ), .TxB_IRQ(TxB_IRQ), |
|
.RxAbort(RxAbort_wb), .RxStatusWriteLatched_sync2(RxStatusWriteLatched_sync2), |
|
.InvalidSymbol(InvalidSymbol), .LatchedCrcError(LatchedCrcError), .RxLength(RxByteCnt), |
.RxLateCollision(RxLateCollision), .ShortFrame(ShortFrame), .DribbleNibble(DribbleNibble), |
.ReceivedPacketTooBig(ReceivedPacketTooBig), .LoadRxStatus(LoadRxStatus), .RetryCntLatched(RetryCntLatched), |
.RetryLimit(RetryLimit), .LateCollLatched(LateCollLatched), .DeferLatched(DeferLatched), |
.RstDeferLatched(RstDeferLatched), |
.CarrierSenseLost(CarrierSenseLost),.ReceivedPacketGood(ReceivedPacketGood), .AddressMiss(AddressMiss), |
.ReceivedPauseFrm(ReceivedPauseFrm) |
|
`ifdef ETH_BIST |
, |
.mbist_si_i (mbist_si_i), |
.mbist_so_o (mbist_so_o), |
.mbist_ctrl_i (mbist_ctrl_i) |
`endif |
`ifdef WISHBONE_DEBUG |
, |
.dbg_dat0(wb_dbg_dat0) |
`endif |
|
); |
|
assign m_wb_adr_o = {m_wb_adr_tmp, 2'h0}; |
|
// Connecting MacStatus module |
eth_macstatus macstatus1 |
( |
.MRxClk(mrx_clk_pad_i), .Reset(wb_rst_i), |
.ReceiveEnd(ReceiveEnd), .ReceivedPacketGood(ReceivedPacketGood), .ReceivedLengthOK(ReceivedLengthOK), |
.RxCrcError(RxCrcError), .MRxErr(MRxErr_Lb), .MRxDV(MRxDV_Lb), |
.RxStateSFD(RxStateSFD), .RxStateData(RxStateData), .RxStatePreamble(RxStatePreamble), |
.RxStateIdle(RxStateIdle), .Transmitting(Transmitting), .RxByteCnt(RxByteCnt), |
.RxByteCntEq0(RxByteCntEq0), .RxByteCntGreat2(RxByteCntGreat2), .RxByteCntMaxFrame(RxByteCntMaxFrame), |
.InvalidSymbol(InvalidSymbol), |
.MRxD(MRxD_Lb), .LatchedCrcError(LatchedCrcError), .Collision(mcoll_pad_i), |
.CollValid(r_CollValid), .RxLateCollision(RxLateCollision), .r_RecSmall(r_RecSmall), |
.r_MinFL(r_MinFL), .r_MaxFL(r_MaxFL), .ShortFrame(ShortFrame), |
.DribbleNibble(DribbleNibble), .ReceivedPacketTooBig(ReceivedPacketTooBig), .r_HugEn(r_HugEn), |
.LoadRxStatus(LoadRxStatus), .RetryCnt(RetryCnt), .StartTxDone(StartTxDone), |
.StartTxAbort(StartTxAbort), .RetryCntLatched(RetryCntLatched), .MTxClk(mtx_clk_pad_i), |
.MaxCollisionOccured(MaxCollisionOccured), .RetryLimit(RetryLimit), .LateCollision(LateCollision), |
.LateCollLatched(LateCollLatched), .DeferIndication(DeferIndication), .DeferLatched(DeferLatched), |
.RstDeferLatched(RstDeferLatched), |
.TxStartFrm(TxStartFrmOut), .StatePreamble(StatePreamble), .StateData(StateData), |
.CarrierSense(CarrierSense_Tx2), .CarrierSenseLost(CarrierSenseLost), .TxUsedData(TxUsedDataIn), |
.LatchedMRxErr(LatchedMRxErr), .Loopback(r_LoopBck), .r_FullD(r_FullD) |
); |
|
|
endmodule |
/verilog/eth/README
0,0 → 1,5
10/100MBps ethernet MAC core |
|
This is based on the core from OpenCores, but heavily modified and improved to provide better bus usage, and buffer configurability. |
|
See the include file, include/eth_defines.v for options. |
/verilog/usbhostslave/directControl.v
0,0 → 1,196
|
// File : ../RTL/hostController/directcontrol.v |
// Generated : 11/10/06 05:37:19 |
// From : ../RTL/hostController/directcontrol.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// directControl |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
module directControl (HCTxPortCntl, HCTxPortData, HCTxPortGnt, HCTxPortRdy, HCTxPortReq, HCTxPortWEn, clk, directControlEn, directControlLineState, rst); |
input HCTxPortGnt; |
input HCTxPortRdy; |
input clk; |
input directControlEn; |
input [1:0] directControlLineState; |
input rst; |
output [7:0] HCTxPortCntl; |
output [7:0] HCTxPortData; |
output HCTxPortReq; |
output HCTxPortWEn; |
|
reg [7:0] HCTxPortCntl, next_HCTxPortCntl; |
reg [7:0] HCTxPortData, next_HCTxPortData; |
wire HCTxPortGnt; |
wire HCTxPortRdy; |
reg HCTxPortReq, next_HCTxPortReq; |
reg HCTxPortWEn, next_HCTxPortWEn; |
wire clk; |
wire directControlEn; |
wire [1:0] directControlLineState; |
wire rst; |
|
// BINARY ENCODED state machine: drctCntl |
// State codes definitions: |
`define START_DC 3'b000 |
`define CHK_DRCT_CNTL 3'b001 |
`define DRCT_CNTL_WAIT_GNT 3'b010 |
`define DRCT_CNTL_CHK_LOOP 3'b011 |
`define DRCT_CNTL_WAIT_RDY 3'b100 |
`define IDLE_FIN 3'b101 |
`define IDLE_WAIT_GNT 3'b110 |
`define IDLE_WAIT_RDY 3'b111 |
|
reg [2:0] CurrState_drctCntl; |
reg [2:0] NextState_drctCntl; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
// diagram ACTION |
|
//-------------------------------------------------------------------- |
// Machine: drctCntl |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (directControlLineState or directControlEn or HCTxPortGnt or HCTxPortRdy or HCTxPortReq or HCTxPortWEn or HCTxPortData or HCTxPortCntl or CurrState_drctCntl) |
begin : drctCntl_NextState |
NextState_drctCntl <= CurrState_drctCntl; |
// Set default values for outputs and signals |
next_HCTxPortReq <= HCTxPortReq; |
next_HCTxPortWEn <= HCTxPortWEn; |
next_HCTxPortData <= HCTxPortData; |
next_HCTxPortCntl <= HCTxPortCntl; |
case (CurrState_drctCntl) |
`START_DC: |
NextState_drctCntl <= `CHK_DRCT_CNTL; |
`CHK_DRCT_CNTL: |
if (directControlEn == 1'b1) |
begin |
NextState_drctCntl <= `DRCT_CNTL_WAIT_GNT; |
next_HCTxPortReq <= 1'b1; |
end |
else |
begin |
NextState_drctCntl <= `IDLE_WAIT_GNT; |
next_HCTxPortReq <= 1'b1; |
end |
`DRCT_CNTL_WAIT_GNT: |
if (HCTxPortGnt == 1'b1) |
NextState_drctCntl <= `DRCT_CNTL_WAIT_RDY; |
`DRCT_CNTL_CHK_LOOP: |
begin |
next_HCTxPortWEn <= 1'b0; |
if (directControlEn == 1'b0) |
begin |
NextState_drctCntl <= `CHK_DRCT_CNTL; |
next_HCTxPortReq <= 1'b0; |
end |
else |
NextState_drctCntl <= `DRCT_CNTL_WAIT_RDY; |
end |
`DRCT_CNTL_WAIT_RDY: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_drctCntl <= `DRCT_CNTL_CHK_LOOP; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= {6'b000000, directControlLineState}; |
next_HCTxPortCntl <= `TX_DIRECT_CONTROL; |
end |
`IDLE_FIN: |
begin |
next_HCTxPortWEn <= 1'b0; |
next_HCTxPortReq <= 1'b0; |
NextState_drctCntl <= `CHK_DRCT_CNTL; |
end |
`IDLE_WAIT_GNT: |
if (HCTxPortGnt == 1'b1) |
NextState_drctCntl <= `IDLE_WAIT_RDY; |
`IDLE_WAIT_RDY: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_drctCntl <= `IDLE_FIN; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= 8'h00; |
next_HCTxPortCntl <= `TX_IDLE; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : drctCntl_CurrentState |
if (rst) |
CurrState_drctCntl <= `START_DC; |
else |
CurrState_drctCntl <= NextState_drctCntl; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : drctCntl_RegOutput |
if (rst) |
begin |
HCTxPortCntl <= 8'h00; |
HCTxPortData <= 8'h00; |
HCTxPortWEn <= 1'b0; |
HCTxPortReq <= 1'b0; |
end |
else |
begin |
HCTxPortCntl <= next_HCTxPortCntl; |
HCTxPortData <= next_HCTxPortData; |
HCTxPortWEn <= next_HCTxPortWEn; |
HCTxPortReq <= next_HCTxPortReq; |
end |
end |
|
endmodule |
/verilog/usbhostslave/processRxByte.v
0,0 → 1,493
|
// File : ../RTL/serialInterfaceEngine/processRxByte.v |
// Generated : 11/10/06 05:37:22 |
// From : ../RTL/serialInterfaceEngine/processRxByte.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// processRxByte |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
`include "usbhostslave_constants_h.v" |
|
module processRxByte (CRC16En, CRC16Result, CRC16UpdateRdy, CRC5En, CRC5Result, CRC5UpdateRdy, CRC5_8Bit, CRCData, RxByteIn, RxCtrlIn, RxCtrlOut, RxDataOutWEn, RxDataOut, clk, processRxByteRdy, processRxDataInWEn, rst, rstCRC); |
input [15:0] CRC16Result; |
input CRC16UpdateRdy; |
input [4:0] CRC5Result; |
input CRC5UpdateRdy; |
input [7:0] RxByteIn; |
input [7:0] RxCtrlIn; |
input clk; |
input processRxDataInWEn; |
input rst; |
output CRC16En; |
output CRC5En; |
output CRC5_8Bit; |
output [7:0] CRCData; |
output [7:0] RxCtrlOut; |
output RxDataOutWEn; |
output [7:0] RxDataOut; |
output processRxByteRdy; |
output rstCRC; |
|
reg CRC16En, next_CRC16En; |
wire [15:0] CRC16Result; |
wire CRC16UpdateRdy; |
reg CRC5En, next_CRC5En; |
wire [4:0] CRC5Result; |
wire CRC5UpdateRdy; |
reg CRC5_8Bit, next_CRC5_8Bit; |
reg [7:0] CRCData, next_CRCData; |
wire [7:0] RxByteIn; |
wire [7:0] RxCtrlIn; |
reg [7:0] RxCtrlOut, next_RxCtrlOut; |
reg RxDataOutWEn, next_RxDataOutWEn; |
reg [7:0] RxDataOut, next_RxDataOut; |
wire clk; |
reg processRxByteRdy, next_processRxByteRdy; |
wire processRxDataInWEn; |
wire rst; |
reg rstCRC, next_rstCRC; |
|
// diagram signals declarations |
reg ACKRxed, next_ACKRxed; |
reg CRCError, next_CRCError; |
reg NAKRxed, next_NAKRxed; |
reg [2:0]RXByteStMachCurrState, next_RXByteStMachCurrState; |
reg [9:0]RXDataByteCnt, next_RXDataByteCnt; |
reg [7:0]RxByte, next_RxByte; |
reg [7:0]RxCtrl, next_RxCtrl; |
reg RxOverflow, next_RxOverflow; |
reg [7:0]RxStatus; |
reg RxTimeOut, next_RxTimeOut; |
reg Signal1, next_Signal1; |
reg bitStuffError, next_bitStuffError; |
reg dataSequence, next_dataSequence; |
reg stallRxed, next_stallRxed; |
|
// BINARY ENCODED state machine: prRxByte |
// State codes definitions: |
`define CHK_ST 4'b0000 |
`define START_PRBY 4'b0001 |
`define WAIT_BYTE 4'b0010 |
`define IDLE_CHK_START 4'b0011 |
`define CHK_SYNC_DO 4'b0100 |
`define CHK_PID_DO_CHK 4'b0101 |
`define CHK_PID_FIRST_BYTE_PROC 4'b0110 |
`define HSHAKE_FIN 4'b0111 |
`define HSHAKE_CHK 4'b1000 |
`define TOKEN_CHK_STRM 4'b1001 |
`define TOKEN_FIN 4'b1010 |
`define DATA_FIN 4'b1011 |
`define DATA_CHK_STRM 4'b1100 |
`define TOKEN_WAIT_CRC 4'b1101 |
`define DATA_WAIT_CRC 4'b1110 |
|
reg [3:0] CurrState_prRxByte; |
reg [3:0] NextState_prRxByte; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
always @ |
(next_CRCError or next_bitStuffError or |
next_RxOverflow or next_NAKRxed or |
next_stallRxed or next_ACKRxed or |
next_dataSequence) |
begin |
RxStatus <= |
{1'b0, next_dataSequence, |
next_ACKRxed, |
next_stallRxed, next_NAKRxed, |
next_RxOverflow, |
next_bitStuffError, next_CRCError }; |
end |
|
//-------------------------------------------------------------------- |
// Machine: prRxByte |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (RxByteIn or RxCtrlIn or RxCtrl or RxStatus or RxByte or RXDataByteCnt or CRC16Result or CRC5Result or RXByteStMachCurrState or processRxDataInWEn or CRC16UpdateRdy or CRC5UpdateRdy or CRCError or bitStuffError or RxOverflow or RxTimeOut or NAKRxed or stallRxed or ACKRxed or dataSequence or RxDataOut or RxCtrlOut or RxDataOutWEn or rstCRC or CRCData or CRC5En or CRC5_8Bit or CRC16En or processRxByteRdy or CurrState_prRxByte) |
begin : prRxByte_NextState |
NextState_prRxByte <= CurrState_prRxByte; |
// Set default values for outputs and signals |
next_RxByte <= RxByte; |
next_RxCtrl <= RxCtrl; |
next_RXByteStMachCurrState <= RXByteStMachCurrState; |
next_CRCError <= CRCError; |
next_bitStuffError <= bitStuffError; |
next_RxOverflow <= RxOverflow; |
next_RxTimeOut <= RxTimeOut; |
next_NAKRxed <= NAKRxed; |
next_stallRxed <= stallRxed; |
next_ACKRxed <= ACKRxed; |
next_dataSequence <= dataSequence; |
next_RxDataOut <= RxDataOut; |
next_RxCtrlOut <= RxCtrlOut; |
next_RxDataOutWEn <= RxDataOutWEn; |
next_rstCRC <= rstCRC; |
next_CRCData <= CRCData; |
next_CRC5En <= CRC5En; |
next_CRC5_8Bit <= CRC5_8Bit; |
next_CRC16En <= CRC16En; |
next_RXDataByteCnt <= RXDataByteCnt; |
next_processRxByteRdy <= processRxByteRdy; |
case (CurrState_prRxByte) |
`CHK_ST: |
if (RXByteStMachCurrState == `HS_BYTE_ST) |
NextState_prRxByte <= `HSHAKE_CHK; |
else if (RXByteStMachCurrState == `TOKEN_BYTE_ST) |
NextState_prRxByte <= `TOKEN_WAIT_CRC; |
else if (RXByteStMachCurrState == `DATA_BYTE_ST) |
NextState_prRxByte <= `DATA_WAIT_CRC; |
else if (RXByteStMachCurrState == `IDLE_BYTE_ST) |
NextState_prRxByte <= `IDLE_CHK_START; |
else if (RXByteStMachCurrState == `CHECK_SYNC_ST) |
NextState_prRxByte <= `CHK_SYNC_DO; |
else if (RXByteStMachCurrState == `CHECK_PID_ST) |
NextState_prRxByte <= `CHK_PID_DO_CHK; |
`START_PRBY: |
begin |
next_RxByte <= 8'h00; |
next_RxCtrl <= 8'h00; |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
next_CRCError <= 1'b0; |
next_bitStuffError <= 1'b0; |
next_RxOverflow <= 1'b0; |
next_RxTimeOut <= 1'b0; |
next_NAKRxed <= 1'b0; |
next_stallRxed <= 1'b0; |
next_ACKRxed <= 1'b0; |
next_dataSequence <= 1'b0; |
next_RxDataOut <= 8'h00; |
next_RxCtrlOut <= 8'h00; |
next_RxDataOutWEn <= 1'b0; |
next_rstCRC <= 1'b0; |
next_CRCData <= 8'h00; |
next_CRC5En <= 1'b0; |
next_CRC5_8Bit <= 1'b0; |
next_CRC16En <= 1'b0; |
next_RXDataByteCnt <= 10'h00; |
next_processRxByteRdy <= 1'b1; |
NextState_prRxByte <= `WAIT_BYTE; |
end |
`WAIT_BYTE: |
if (processRxDataInWEn == 1'b1) |
begin |
NextState_prRxByte <= `CHK_ST; |
next_RxByte <= RxByteIn; |
next_RxCtrl <= RxCtrlIn; |
next_processRxByteRdy <= 1'b0; |
end |
`HSHAKE_FIN: |
begin |
next_RxDataOutWEn <= 1'b0; |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
NextState_prRxByte <= `WAIT_BYTE; |
next_processRxByteRdy <= 1'b1; |
end |
`HSHAKE_CHK: |
begin |
NextState_prRxByte <= `HSHAKE_FIN; |
if (RxCtrl != `DATA_STOP) //If more than PID rxed, then report error |
next_RxOverflow <= 1'b1; |
next_RxDataOut <= RxStatus; |
next_RxCtrlOut <= `RX_PACKET_STOP; |
next_RxDataOutWEn <= 1'b1; |
end |
`CHK_PID_DO_CHK: |
if ((RxByte[7:4] ^ RxByte[3:0] ) != 4'hf) |
begin |
NextState_prRxByte <= `WAIT_BYTE; |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
next_processRxByteRdy <= 1'b1; |
end |
else |
begin |
NextState_prRxByte <= `CHK_PID_FIRST_BYTE_PROC; |
next_CRCError <= 1'b0; |
next_bitStuffError <= 1'b0; |
next_RxOverflow <= 1'b0; |
next_NAKRxed <= 1'b0; |
next_stallRxed <= 1'b0; |
next_ACKRxed <= 1'b0; |
next_dataSequence <= 1'b0; |
next_RxTimeOut <= 1'b0; |
next_RXDataByteCnt <= 10'h000; |
next_RxDataOut <= RxByte; |
next_RxCtrlOut <= `RX_PACKET_START; |
next_RxDataOutWEn <= 1'b1; |
next_rstCRC <= 1'b1; |
end |
`CHK_PID_FIRST_BYTE_PROC: |
begin |
next_rstCRC <= 1'b0; |
next_RxDataOutWEn <= 1'b0; |
case (RxByte[1:0] ) |
`SPECIAL: //Special PID. |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
`TOKEN: //Token PID |
begin |
next_RXByteStMachCurrState <= `TOKEN_BYTE_ST; |
next_RXDataByteCnt <= 0; |
end |
`HANDSHAKE: //Handshake PID |
begin |
case (RxByte[3:2] ) |
2'b00: |
next_ACKRxed <= 1'b1; |
2'b10: |
next_NAKRxed <= 1'b1; |
2'b11: |
next_stallRxed <= 1'b1; |
default: |
begin |
$display ("Invalid Handshake PID detected in ProcessRXByte\n"); |
end |
endcase |
next_RXByteStMachCurrState <= `HS_BYTE_ST; |
end |
`DATA: //Data PID |
begin |
case (RxByte[3:2] ) |
2'b00: |
next_dataSequence <= 1'b0; |
2'b10: |
next_dataSequence <= 1'b1; |
default: |
$display ("Invalid DATA PID detected in ProcessRXByte\n"); |
endcase |
next_RXByteStMachCurrState <= `DATA_BYTE_ST; |
next_RXDataByteCnt <= 0; |
end |
endcase |
NextState_prRxByte <= `WAIT_BYTE; |
next_processRxByteRdy <= 1'b1; |
end |
`DATA_FIN: |
begin |
next_CRC16En <= 1'b0; |
next_RxDataOutWEn <= 1'b0; |
NextState_prRxByte <= `WAIT_BYTE; |
next_processRxByteRdy <= 1'b1; |
end |
`DATA_CHK_STRM: |
begin |
next_RXDataByteCnt <= RXDataByteCnt + 1'b1; |
case (RxCtrl) |
`DATA_STOP: |
begin |
if (CRC16Result != 16'hb001) |
next_CRCError <= 1'b1; |
next_RxDataOut <= RxStatus; |
next_RxCtrlOut <= `RX_PACKET_STOP; |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
end |
`DATA_BIT_STUFF_ERROR: |
begin |
next_bitStuffError <= 1'b1; |
next_RxDataOut <= RxStatus; |
next_RxCtrlOut <= `RX_PACKET_STOP; |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
end |
`DATA_STREAM: |
begin |
next_RxDataOut <= RxByte; |
next_RxCtrlOut <= `RX_PACKET_STREAM; |
next_CRCData <= RxByte; |
next_CRC16En <= 1'b1; |
end |
default: |
begin |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
end |
endcase |
next_RxDataOutWEn <= 1'b1; |
NextState_prRxByte <= `DATA_FIN; |
end |
`DATA_WAIT_CRC: |
if (CRC16UpdateRdy == 1'b1) |
NextState_prRxByte <= `DATA_CHK_STRM; |
`TOKEN_CHK_STRM: |
begin |
next_RXDataByteCnt <= RXDataByteCnt + 1'b1; |
case (RxCtrl) |
`DATA_STOP: |
begin |
if (CRC5Result != 5'h6) |
next_CRCError <= 1'b1; |
next_RxDataOut <= RxStatus; |
next_RxCtrlOut <= `RX_PACKET_STOP; |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
end |
`DATA_BIT_STUFF_ERROR: |
begin |
next_bitStuffError <= 1'b1; |
next_RxDataOut <= RxStatus; |
next_RxCtrlOut <= `RX_PACKET_STOP; |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
end |
`DATA_STREAM: |
begin |
if (RXDataByteCnt > 10'h2) |
begin |
next_RxOverflow <= 1'b1; |
next_RxDataOut <= RxStatus; |
next_RxCtrlOut <= `RX_PACKET_STOP; |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
end |
else |
begin |
next_RxDataOut <= RxByte; |
next_RxCtrlOut <= `RX_PACKET_STREAM; |
next_CRCData <= RxByte; |
next_CRC5_8Bit <= 1'b1; |
next_CRC5En <= 1'b1; |
end |
end |
default: |
begin |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
end |
endcase |
next_RxDataOutWEn <= 1'b1; |
NextState_prRxByte <= `TOKEN_FIN; |
end |
`TOKEN_FIN: |
begin |
next_CRC5En <= 1'b0; |
next_RxDataOutWEn <= 1'b0; |
NextState_prRxByte <= `WAIT_BYTE; |
next_processRxByteRdy <= 1'b1; |
end |
`TOKEN_WAIT_CRC: |
if (CRC5UpdateRdy == 1'b1) |
NextState_prRxByte <= `TOKEN_CHK_STRM; |
`CHK_SYNC_DO: |
begin |
if (RxByte == `SYNC_BYTE) |
next_RXByteStMachCurrState <= `CHECK_PID_ST; |
else |
next_RXByteStMachCurrState <= `IDLE_BYTE_ST; |
NextState_prRxByte <= `WAIT_BYTE; |
next_processRxByteRdy <= 1'b1; |
end |
`IDLE_CHK_START: |
begin |
if (RxCtrl == `DATA_START) |
next_RXByteStMachCurrState <= `CHECK_SYNC_ST; |
NextState_prRxByte <= `WAIT_BYTE; |
next_processRxByteRdy <= 1'b1; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : prRxByte_CurrentState |
if (rst) |
CurrState_prRxByte <= `START_PRBY; |
else |
CurrState_prRxByte <= NextState_prRxByte; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : prRxByte_RegOutput |
if (rst) |
begin |
RxByte <= 8'h00; |
RxCtrl <= 8'h00; |
RXByteStMachCurrState <= `IDLE_BYTE_ST; |
CRCError <= 1'b0; |
bitStuffError <= 1'b0; |
RxOverflow <= 1'b0; |
RxTimeOut <= 1'b0; |
NAKRxed <= 1'b0; |
stallRxed <= 1'b0; |
ACKRxed <= 1'b0; |
dataSequence <= 1'b0; |
RXDataByteCnt <= 10'h00; |
RxDataOut <= 8'h00; |
RxCtrlOut <= 8'h00; |
RxDataOutWEn <= 1'b0; |
rstCRC <= 1'b0; |
CRCData <= 8'h00; |
CRC5En <= 1'b0; |
CRC5_8Bit <= 1'b0; |
CRC16En <= 1'b0; |
processRxByteRdy <= 1'b1; |
end |
else |
begin |
RxByte <= next_RxByte; |
RxCtrl <= next_RxCtrl; |
RXByteStMachCurrState <= next_RXByteStMachCurrState; |
CRCError <= next_CRCError; |
bitStuffError <= next_bitStuffError; |
RxOverflow <= next_RxOverflow; |
RxTimeOut <= next_RxTimeOut; |
NAKRxed <= next_NAKRxed; |
stallRxed <= next_stallRxed; |
ACKRxed <= next_ACKRxed; |
dataSequence <= next_dataSequence; |
RXDataByteCnt <= next_RXDataByteCnt; |
RxDataOut <= next_RxDataOut; |
RxCtrlOut <= next_RxCtrlOut; |
RxDataOutWEn <= next_RxDataOutWEn; |
rstCRC <= next_rstCRC; |
CRCData <= next_CRCData; |
CRC5En <= next_CRC5En; |
CRC5_8Bit <= next_CRC5_8Bit; |
CRC16En <= next_CRC16En; |
processRxByteRdy <= next_processRxByteRdy; |
end |
end |
|
endmodule |
/verilog/usbhostslave/slaveSendPacket.v
0,0 → 1,252
|
// File : ../RTL/slaveController/slaveSendpacket.v |
// Generated : 11/10/06 05:37:26 |
// From : ../RTL/slaveController/slaveSendpacket.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// slaveSendPacket |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
`include "usbhostslave_constants_h.v" |
|
module slaveSendPacket (PID, SCTxPortCntl, SCTxPortData, SCTxPortGnt, SCTxPortRdy, SCTxPortReq, SCTxPortWEn, clk, fifoData, fifoEmpty, fifoReadEn, rst, sendPacketRdy, sendPacketWEn); |
input [3:0] PID; |
input SCTxPortGnt; |
input SCTxPortRdy; |
input clk; |
input [7:0] fifoData; |
input fifoEmpty; |
input rst; |
input sendPacketWEn; |
output [7:0] SCTxPortCntl; |
output [7:0] SCTxPortData; |
output SCTxPortReq; |
output SCTxPortWEn; |
output fifoReadEn; |
output sendPacketRdy; |
|
wire [3:0] PID; |
reg [7:0] SCTxPortCntl, next_SCTxPortCntl; |
reg [7:0] SCTxPortData, next_SCTxPortData; |
wire SCTxPortGnt; |
wire SCTxPortRdy; |
reg SCTxPortReq, next_SCTxPortReq; |
reg SCTxPortWEn, next_SCTxPortWEn; |
wire clk; |
wire [7:0] fifoData; |
wire fifoEmpty; |
reg fifoReadEn, next_fifoReadEn; |
wire rst; |
reg sendPacketRdy, next_sendPacketRdy; |
wire sendPacketWEn; |
|
// diagram signals declarations |
reg [7:0]PIDNotPID; |
|
// BINARY ENCODED state machine: slvSndPkt |
// State codes definitions: |
`define START_SP1 4'b0000 |
`define SP_WAIT_ENABLE 4'b0001 |
`define SP1_WAIT_GNT 4'b0010 |
`define SP_SEND_PID_WAIT_RDY 4'b0011 |
`define SP_SEND_PID_FIN 4'b0100 |
`define FIN_SP1 4'b0101 |
`define SP_D0_D1_READ_FIFO 4'b0110 |
`define SP_D0_D1_WAIT_READ_FIFO 4'b0111 |
`define SP_D0_D1_FIFO_EMPTY 4'b1000 |
`define SP_D0_D1_FIN 4'b1001 |
`define SP_D0_D1_TERM_BYTE 4'b1010 |
`define SP_NOT_DATA 4'b1011 |
`define SP_D0_D1_CLR_WEN 4'b1100 |
`define SP_D0_D1_CLR_REN 4'b1101 |
|
reg [3:0] CurrState_slvSndPkt; |
reg [3:0] NextState_slvSndPkt; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
always @(PID) |
begin |
PIDNotPID <= { (PID ^ 4'hf), PID }; |
end |
|
//-------------------------------------------------------------------- |
// Machine: slvSndPkt |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (PIDNotPID or fifoData or sendPacketWEn or SCTxPortGnt or SCTxPortRdy or PID or fifoEmpty or sendPacketRdy or SCTxPortReq or SCTxPortWEn or SCTxPortData or SCTxPortCntl or fifoReadEn or CurrState_slvSndPkt) |
begin : slvSndPkt_NextState |
NextState_slvSndPkt <= CurrState_slvSndPkt; |
// Set default values for outputs and signals |
next_sendPacketRdy <= sendPacketRdy; |
next_SCTxPortReq <= SCTxPortReq; |
next_SCTxPortWEn <= SCTxPortWEn; |
next_SCTxPortData <= SCTxPortData; |
next_SCTxPortCntl <= SCTxPortCntl; |
next_fifoReadEn <= fifoReadEn; |
case (CurrState_slvSndPkt) |
`START_SP1: |
NextState_slvSndPkt <= `SP_WAIT_ENABLE; |
`SP_WAIT_ENABLE: |
if (sendPacketWEn == 1'b1) |
begin |
NextState_slvSndPkt <= `SP1_WAIT_GNT; |
next_sendPacketRdy <= 1'b0; |
next_SCTxPortReq <= 1'b1; |
end |
`SP1_WAIT_GNT: |
if (SCTxPortGnt == 1'b1) |
NextState_slvSndPkt <= `SP_SEND_PID_WAIT_RDY; |
`FIN_SP1: |
begin |
NextState_slvSndPkt <= `SP_WAIT_ENABLE; |
next_sendPacketRdy <= 1'b1; |
next_SCTxPortReq <= 1'b0; |
end |
`SP_NOT_DATA: |
NextState_slvSndPkt <= `FIN_SP1; |
`SP_SEND_PID_WAIT_RDY: |
if (SCTxPortRdy == 1'b1) |
begin |
NextState_slvSndPkt <= `SP_SEND_PID_FIN; |
next_SCTxPortWEn <= 1'b1; |
next_SCTxPortData <= PIDNotPID; |
next_SCTxPortCntl <= `TX_PACKET_START; |
end |
`SP_SEND_PID_FIN: |
begin |
next_SCTxPortWEn <= 1'b0; |
if (PID == `DATA0 || PID == `DATA1) |
NextState_slvSndPkt <= `SP_D0_D1_FIFO_EMPTY; |
else |
NextState_slvSndPkt <= `SP_NOT_DATA; |
end |
`SP_D0_D1_READ_FIFO: |
begin |
next_SCTxPortWEn <= 1'b1; |
next_SCTxPortData <= fifoData; |
next_SCTxPortCntl <= `TX_PACKET_STREAM; |
NextState_slvSndPkt <= `SP_D0_D1_CLR_WEN; |
end |
`SP_D0_D1_WAIT_READ_FIFO: |
if (SCTxPortRdy == 1'b1) |
begin |
NextState_slvSndPkt <= `SP_D0_D1_CLR_REN; |
next_fifoReadEn <= 1'b1; |
end |
`SP_D0_D1_FIFO_EMPTY: |
if (fifoEmpty == 1'b0) |
NextState_slvSndPkt <= `SP_D0_D1_WAIT_READ_FIFO; |
else |
NextState_slvSndPkt <= `SP_D0_D1_TERM_BYTE; |
`SP_D0_D1_FIN: |
begin |
next_SCTxPortWEn <= 1'b0; |
NextState_slvSndPkt <= `FIN_SP1; |
end |
`SP_D0_D1_TERM_BYTE: |
if (SCTxPortRdy == 1'b1) |
begin |
NextState_slvSndPkt <= `SP_D0_D1_FIN; |
//Last byte is not valid data, |
//but the 'TX_PACKET_STOP' flag is required |
//by the SIE state machine to detect end of data packet |
next_SCTxPortWEn <= 1'b1; |
next_SCTxPortData <= 8'h00; |
next_SCTxPortCntl <= `TX_PACKET_STOP; |
end |
`SP_D0_D1_CLR_WEN: |
begin |
next_SCTxPortWEn <= 1'b0; |
NextState_slvSndPkt <= `SP_D0_D1_FIFO_EMPTY; |
end |
`SP_D0_D1_CLR_REN: |
begin |
next_fifoReadEn <= 1'b0; |
NextState_slvSndPkt <= `SP_D0_D1_READ_FIFO; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : slvSndPkt_CurrentState |
if (rst) |
CurrState_slvSndPkt <= `START_SP1; |
else |
CurrState_slvSndPkt <= NextState_slvSndPkt; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : slvSndPkt_RegOutput |
if (rst) |
begin |
sendPacketRdy <= 1'b1; |
SCTxPortReq <= 1'b0; |
SCTxPortWEn <= 1'b0; |
SCTxPortData <= 8'h00; |
SCTxPortCntl <= 8'h00; |
fifoReadEn <= 1'b0; |
end |
else |
begin |
sendPacketRdy <= next_sendPacketRdy; |
SCTxPortReq <= next_SCTxPortReq; |
SCTxPortWEn <= next_SCTxPortWEn; |
SCTxPortData <= next_SCTxPortData; |
SCTxPortCntl <= next_SCTxPortCntl; |
fifoReadEn <= next_fifoReadEn; |
end |
end |
|
endmodule |
/verilog/usbhostslave/hostSlaveMuxBI.v
0,0 → 1,124
////////////////////////////////////////////////////////////////////// |
//// //// |
//// hostSlaveMuxBI.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_hostslave_h.v" |
|
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; |
output [7:0] dataOut; |
input hostSlaveMuxSel; |
output hostMode; |
input rstFromWire; |
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 |
/verilog/usbhostslave/processTxByte.v
0,0 → 1,448
|
// File : ../RTL/serialInterfaceEngine/processTxByte.v |
// Generated : 11/10/06 05:37:23 |
// From : ../RTL/serialInterfaceEngine/processTxByte.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// processTxByte |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
`include "usbhostslave_constants_h.v" |
|
module processTxByte (JBit, KBit, TxByteCtrlIn, TxByteFullSpeedRateIn, TxByteIn, USBWireCtrl, USBWireData, USBWireFullSpeedRate, USBWireGnt, USBWireRdy, USBWireReq, USBWireWEn, clk, processTxByteRdy, processTxByteWEn, rst); |
input [1:0] JBit; |
input [1:0] KBit; |
input [7:0] TxByteCtrlIn; |
input TxByteFullSpeedRateIn; |
input [7:0] TxByteIn; |
input USBWireGnt; |
input USBWireRdy; |
input clk; |
input processTxByteWEn; |
input rst; |
output USBWireCtrl; |
output [1:0] USBWireData; |
output USBWireFullSpeedRate; |
output USBWireReq; |
output USBWireWEn; |
output processTxByteRdy; |
|
wire [1:0] JBit; |
wire [1:0] KBit; |
wire [7:0] TxByteCtrlIn; |
wire TxByteFullSpeedRateIn; |
wire [7:0] TxByteIn; |
reg USBWireCtrl, next_USBWireCtrl; |
reg [1:0] USBWireData, next_USBWireData; |
reg USBWireFullSpeedRate, next_USBWireFullSpeedRate; |
wire USBWireGnt; |
wire USBWireRdy; |
reg USBWireReq, next_USBWireReq; |
reg USBWireWEn, next_USBWireWEn; |
wire clk; |
reg processTxByteRdy, next_processTxByteRdy; |
wire processTxByteWEn; |
wire rst; |
|
// diagram signals declarations |
reg [1:0]TXLineState, next_TXLineState; |
reg [3:0]TXOneCount, next_TXOneCount; |
reg [7:0]TxByteCtrl, next_TxByteCtrl; |
reg TxByteFullSpeedRate, next_TxByteFullSpeedRate; |
reg [7:0]TxByte, next_TxByte; |
reg [3:0]i, next_i; |
|
// BINARY ENCODED state machine: prcTxB |
// State codes definitions: |
`define START_PTBY 5'b00000 |
`define PTBY_WAIT_EN 5'b00001 |
`define SEND_BYTE_UPDATE_BYTE 5'b00010 |
`define SEND_BYTE_WAIT_RDY 5'b00011 |
`define SEND_BYTE_CHK 5'b00100 |
`define SEND_BYTE_BIT_STUFF 5'b00101 |
`define SEND_BYTE_WAIT_RDY2 5'b00110 |
`define SEND_BYTE_CHK_FIN 5'b00111 |
`define PTBY_WAIT_GNT 5'b01000 |
`define STOP_SND_SE0_2 5'b01001 |
`define STOP_SND_SE0_1 5'b01010 |
`define STOP_CHK 5'b01011 |
`define STOP_SND_J 5'b01100 |
`define STOP_SND_IDLE 5'b01101 |
`define STOP_FIN 5'b01110 |
`define WAIT_RDY_WIRE 5'b01111 |
`define WAIT_RDY_PKT 5'b10000 |
`define LS_START_SND_IDLE3 5'b10001 |
`define LS_START_SND_J1 5'b10010 |
`define LS_START_SND_IDLE1 5'b10011 |
`define LS_START_SND_IDLE2 5'b10100 |
`define LS_START_FIN 5'b10101 |
`define LS_START_W_RDY1 5'b10110 |
`define LS_START_W_RDY2 5'b10111 |
`define LS_START_W_RDY3 5'b11000 |
`define STOP_W_RDY1 5'b11001 |
`define STOP_W_RDY2 5'b11010 |
`define STOP_W_RDY3 5'b11011 |
`define STOP_W_RDY4 5'b11100 |
|
reg [4:0] CurrState_prcTxB; |
reg [4:0] NextState_prcTxB; |
|
|
//-------------------------------------------------------------------- |
// Machine: prcTxB |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (TxByteIn or TxByteCtrlIn or TxByteFullSpeedRateIn or JBit or i or TxByte or TXOneCount or TXLineState or KBit or processTxByteWEn or USBWireGnt or USBWireRdy or TxByteFullSpeedRate or TxByteCtrl or processTxByteRdy or USBWireData or USBWireCtrl or USBWireReq or USBWireWEn or USBWireFullSpeedRate or CurrState_prcTxB) |
begin : prcTxB_NextState |
NextState_prcTxB <= CurrState_prcTxB; |
// Set default values for outputs and signals |
next_processTxByteRdy <= processTxByteRdy; |
next_USBWireData <= USBWireData; |
next_USBWireCtrl <= USBWireCtrl; |
next_USBWireReq <= USBWireReq; |
next_USBWireWEn <= USBWireWEn; |
next_i <= i; |
next_TxByte <= TxByte; |
next_TxByteCtrl <= TxByteCtrl; |
next_TXLineState <= TXLineState; |
next_TXOneCount <= TXOneCount; |
next_USBWireFullSpeedRate <= USBWireFullSpeedRate; |
next_TxByteFullSpeedRate <= TxByteFullSpeedRate; |
case (CurrState_prcTxB) |
`START_PTBY: |
begin |
next_processTxByteRdy <= 1'b0; |
next_USBWireData <= 2'b00; |
next_USBWireCtrl <= `TRI_STATE; |
next_USBWireReq <= 1'b0; |
next_USBWireWEn <= 1'b0; |
next_i <= 4'h0; |
next_TxByte <= 8'h00; |
next_TxByteCtrl <= 8'h00; |
next_TXLineState <= 2'b0; |
next_TXOneCount <= 4'h0; |
next_USBWireFullSpeedRate <= 1'b0; |
next_TxByteFullSpeedRate <= 1'b0; |
NextState_prcTxB <= `PTBY_WAIT_EN; |
end |
`PTBY_WAIT_EN: |
begin |
next_processTxByteRdy <= 1'b1; |
if ((processTxByteWEn == 1'b1) && (TxByteCtrlIn == `DATA_START)) |
begin |
NextState_prcTxB <= `PTBY_WAIT_GNT; |
next_processTxByteRdy <= 1'b0; |
next_TxByte <= TxByteIn; |
next_TxByteCtrl <= TxByteCtrlIn; |
next_TxByteFullSpeedRate <= TxByteFullSpeedRateIn; |
next_USBWireFullSpeedRate <= TxByteFullSpeedRateIn; |
next_TXOneCount <= 4'h0; |
next_TXLineState <= JBit; |
next_USBWireReq <= 1'b1; |
end |
else if (processTxByteWEn == 1'b1) |
begin |
NextState_prcTxB <= `SEND_BYTE_UPDATE_BYTE; |
next_processTxByteRdy <= 1'b0; |
next_TxByte <= TxByteIn; |
next_TxByteCtrl <= TxByteCtrlIn; |
next_TxByteFullSpeedRate <= TxByteFullSpeedRateIn; |
next_USBWireFullSpeedRate <= TxByteFullSpeedRateIn; |
next_i <= 4'h0; |
end |
end |
`PTBY_WAIT_GNT: |
if (USBWireGnt == 1'b1) |
NextState_prcTxB <= `WAIT_RDY_WIRE; |
`WAIT_RDY_WIRE: |
if ((USBWireRdy == 1'b1) && (TxByteFullSpeedRate == 1'b0)) |
NextState_prcTxB <= `LS_START_SND_IDLE1; |
else if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `WAIT_RDY_PKT; |
//actively drive the first J bit |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
end |
`WAIT_RDY_PKT: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_prcTxB <= `SEND_BYTE_UPDATE_BYTE; |
next_i <= 4'h0; |
end |
`SEND_BYTE_UPDATE_BYTE: |
begin |
next_i <= i + 1'b1; |
next_TxByte <= {1'b0, TxByte[7:1] }; |
if (TxByte[0] == 1'b1) //If this bit is 1, then |
next_TXOneCount <= TXOneCount + 1'b1; |
//increment 'TXOneCount' |
else //else this is a zero bit |
begin |
next_TXOneCount <= 4'h0; |
//reset 'TXOneCount' |
if (TXLineState == JBit) |
next_TXLineState <= KBit; |
//toggle the line state |
else |
next_TXLineState <= JBit; |
end |
NextState_prcTxB <= `SEND_BYTE_WAIT_RDY; |
end |
`SEND_BYTE_WAIT_RDY: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `SEND_BYTE_CHK; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= TXLineState; |
next_USBWireCtrl <= `DRIVE; |
end |
`SEND_BYTE_CHK: |
begin |
next_USBWireWEn <= 1'b0; |
if (TXOneCount == `MAX_CONSEC_SAME_BITS) |
NextState_prcTxB <= `SEND_BYTE_BIT_STUFF; |
else if (i != 4'h8) |
NextState_prcTxB <= `SEND_BYTE_UPDATE_BYTE; |
else |
NextState_prcTxB <= `STOP_CHK; |
end |
`SEND_BYTE_BIT_STUFF: |
begin |
next_TXOneCount <= 4'h0; |
//reset 'TXOneCount' |
if (TXLineState == JBit) |
next_TXLineState <= KBit; |
//toggle the line state |
else |
next_TXLineState <= JBit; |
NextState_prcTxB <= `SEND_BYTE_WAIT_RDY2; |
end |
`SEND_BYTE_WAIT_RDY2: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `SEND_BYTE_CHK_FIN; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= TXLineState; |
next_USBWireCtrl <= `DRIVE; |
end |
`SEND_BYTE_CHK_FIN: |
begin |
next_USBWireWEn <= 1'b0; |
if (i == 4'h8) |
NextState_prcTxB <= `STOP_CHK; |
else |
NextState_prcTxB <= `SEND_BYTE_UPDATE_BYTE; |
end |
`STOP_SND_SE0_2: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_prcTxB <= `STOP_W_RDY2; |
end |
`STOP_SND_SE0_1: |
NextState_prcTxB <= `STOP_W_RDY1; |
`STOP_CHK: |
if (TxByteCtrl == `DATA_STOP) |
NextState_prcTxB <= `STOP_SND_SE0_1; |
else |
NextState_prcTxB <= `PTBY_WAIT_EN; |
`STOP_SND_J: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_prcTxB <= `STOP_W_RDY3; |
end |
`STOP_SND_IDLE: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_prcTxB <= `STOP_W_RDY4; |
end |
`STOP_FIN: |
begin |
next_USBWireWEn <= 1'b0; |
next_USBWireReq <= 1'b0; |
//release the wire |
NextState_prcTxB <= `PTBY_WAIT_EN; |
end |
`STOP_W_RDY1: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `STOP_SND_SE0_2; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= `SE0; |
next_USBWireCtrl <= `DRIVE; |
end |
`STOP_W_RDY2: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `STOP_SND_J; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= `SE0; |
next_USBWireCtrl <= `DRIVE; |
end |
`STOP_W_RDY3: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `STOP_SND_IDLE; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `DRIVE; |
end |
`STOP_W_RDY4: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `STOP_FIN; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `TRI_STATE; |
end |
`LS_START_SND_IDLE3: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_prcTxB <= `LS_START_W_RDY2; |
end |
`LS_START_SND_J1: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_prcTxB <= `LS_START_W_RDY3; |
end |
`LS_START_SND_IDLE1: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `LS_START_SND_IDLE2; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `TRI_STATE; |
end |
`LS_START_SND_IDLE2: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_prcTxB <= `LS_START_W_RDY1; |
end |
`LS_START_FIN: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_prcTxB <= `SEND_BYTE_UPDATE_BYTE; |
next_i <= 4'h0; |
end |
`LS_START_W_RDY1: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `LS_START_SND_IDLE3; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `TRI_STATE; |
end |
`LS_START_W_RDY2: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `LS_START_SND_J1; |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `TRI_STATE; |
end |
`LS_START_W_RDY3: |
if (USBWireRdy == 1'b1) |
begin |
NextState_prcTxB <= `LS_START_FIN; |
//Drive the first JBit |
next_USBWireWEn <= 1'b1; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `DRIVE; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : prcTxB_CurrentState |
if (rst) |
CurrState_prcTxB <= `START_PTBY; |
else |
CurrState_prcTxB <= NextState_prcTxB; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : prcTxB_RegOutput |
if (rst) |
begin |
i <= 4'h0; |
TxByte <= 8'h00; |
TxByteCtrl <= 8'h00; |
TXLineState <= 2'b0; |
TXOneCount <= 4'h0; |
TxByteFullSpeedRate <= 1'b0; |
processTxByteRdy <= 1'b0; |
USBWireData <= 2'b00; |
USBWireCtrl <= `TRI_STATE; |
USBWireReq <= 1'b0; |
USBWireWEn <= 1'b0; |
USBWireFullSpeedRate <= 1'b0; |
end |
else |
begin |
i <= next_i; |
TxByte <= next_TxByte; |
TxByteCtrl <= next_TxByteCtrl; |
TXLineState <= next_TXLineState; |
TXOneCount <= next_TXOneCount; |
TxByteFullSpeedRate <= next_TxByteFullSpeedRate; |
processTxByteRdy <= next_processTxByteRdy; |
USBWireData <= next_USBWireData; |
USBWireCtrl <= next_USBWireCtrl; |
USBWireReq <= next_USBWireReq; |
USBWireWEn <= next_USBWireWEn; |
USBWireFullSpeedRate <= next_USBWireFullSpeedRate; |
end |
end |
|
endmodule |
/verilog/usbhostslave/slavecontroller.v
0,0 → 1,475
|
// File : ../RTL/slaveController/slavecontroller.v |
// Generated : 11/10/06 05:37:25 |
// From : ../RTL/slaveController/slavecontroller.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// slaveController |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
`include "usbhostslave_slavecontrol_h.v" |
`include "usbhostslave_constants_h.v" |
|
|
module slavecontroller (CRCError, NAKSent, RxByte, RxDataWEn, RxOverflow, RxStatus, RxTimeOut, SCGlobalEn, SOFRxed, USBEndPControlReg, USBEndPNakTransTypeReg, USBEndPTransTypeReg, USBEndP, USBTgtAddress, bitStuffError, clk, clrEPRdy, endPMuxErrorsWEn, endPointReadyToGetPkt, frameNum, getPacketREn, getPacketRdy, rst, sendPacketPID, sendPacketRdy, sendPacketWEn, stallSent, transDone); |
input CRCError; |
input [7:0] RxByte; |
input RxDataWEn; |
input RxOverflow; |
input [7:0] RxStatus; |
input RxTimeOut; |
input SCGlobalEn; |
input [4:0] USBEndPControlReg; |
input [6:0] USBTgtAddress; |
input bitStuffError; |
input clk; |
input getPacketRdy; |
input rst; |
input sendPacketRdy; |
output NAKSent; |
output SOFRxed; |
output [1:0] USBEndPNakTransTypeReg; |
output [1:0] USBEndPTransTypeReg; |
output [3:0] USBEndP; |
output clrEPRdy; |
output endPMuxErrorsWEn; |
output endPointReadyToGetPkt; |
output [10:0] frameNum; |
output getPacketREn; |
output [3:0] sendPacketPID; |
output sendPacketWEn; |
output stallSent; |
output transDone; |
|
wire CRCError; |
reg NAKSent, next_NAKSent; |
wire [7:0] RxByte; |
wire RxDataWEn; |
wire RxOverflow; |
wire [7:0] RxStatus; |
wire RxTimeOut; |
wire SCGlobalEn; |
reg SOFRxed, next_SOFRxed; |
wire [4:0] USBEndPControlReg; |
reg [1:0] USBEndPNakTransTypeReg, next_USBEndPNakTransTypeReg; |
reg [1:0] USBEndPTransTypeReg, next_USBEndPTransTypeReg; |
reg [3:0] USBEndP, next_USBEndP; |
wire [6:0] USBTgtAddress; |
wire bitStuffError; |
wire clk; |
reg clrEPRdy, next_clrEPRdy; |
reg endPMuxErrorsWEn, next_endPMuxErrorsWEn; |
reg endPointReadyToGetPkt, next_endPointReadyToGetPkt; |
reg [10:0] frameNum, next_frameNum; |
reg getPacketREn, next_getPacketREn; |
wire getPacketRdy; |
wire rst; |
reg [3:0] sendPacketPID, next_sendPacketPID; |
wire sendPacketRdy; |
reg sendPacketWEn, next_sendPacketWEn; |
reg stallSent, next_stallSent; |
reg transDone, next_transDone; |
|
// diagram signals declarations |
reg [7:0]PIDByte, next_PIDByte; |
reg [6:0]USBAddress, next_USBAddress; |
reg [4:0]USBEndPControlRegCopy, next_USBEndPControlRegCopy; |
reg [7:0]addrEndPTemp, next_addrEndPTemp; |
reg [7:0]endpCRCTemp, next_endpCRCTemp; |
reg [1:0]tempUSBEndPTransTypeReg, next_tempUSBEndPTransTypeReg; |
|
// BINARY ENCODED state machine: slvCntrl |
// State codes definitions: |
`define WAIT_RX1 5'b00000 |
`define FIN_SC 5'b00001 |
`define GET_TOKEN_WAIT_CRC 5'b00010 |
`define GET_TOKEN_WAIT_ADDR 5'b00011 |
`define GET_TOKEN_WAIT_STOP 5'b00100 |
`define CHK_PID 5'b00101 |
`define GET_TOKEN_CHK_SOF 5'b00110 |
`define PID_ERROR 5'b00111 |
`define CHK_RDY 5'b01000 |
`define IN_NAK_STALL 5'b01001 |
`define IN_CHK_RDY 5'b01010 |
`define SETUP_OUT_CHK 5'b01011 |
`define SETUP_OUT_SEND 5'b01100 |
`define SETUP_OUT_GET_PKT 5'b01101 |
`define START_S1 5'b01110 |
`define GET_TOKEN_DELAY 5'b01111 |
`define GET_TOKEN_CHK_ADDR 5'b10000 |
`define IN_RESP_GET_RESP 5'b10001 |
`define IN_RESP_DATA 5'b10010 |
`define IN_RESP_CHK_ISO 5'b10011 |
|
reg [4:0] CurrState_slvCntrl; |
reg [4:0] NextState_slvCntrl; |
|
|
//-------------------------------------------------------------------- |
// Machine: slvCntrl |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (RxByte or tempUSBEndPTransTypeReg or endpCRCTemp or addrEndPTemp or USBEndPControlReg or RxDataWEn or RxStatus or PIDByte or USBEndPControlRegCopy or NAKSent or sendPacketRdy or getPacketRdy or CRCError or bitStuffError or RxOverflow or RxTimeOut or USBEndP or USBAddress or USBTgtAddress or SCGlobalEn or stallSent or SOFRxed or transDone or clrEPRdy or endPMuxErrorsWEn or getPacketREn or sendPacketWEn or sendPacketPID or USBEndPTransTypeReg or USBEndPNakTransTypeReg or frameNum or endPointReadyToGetPkt or CurrState_slvCntrl) |
begin : slvCntrl_NextState |
NextState_slvCntrl <= CurrState_slvCntrl; |
// Set default values for outputs and signals |
next_stallSent <= stallSent; |
next_NAKSent <= NAKSent; |
next_SOFRxed <= SOFRxed; |
next_PIDByte <= PIDByte; |
next_transDone <= transDone; |
next_clrEPRdy <= clrEPRdy; |
next_endPMuxErrorsWEn <= endPMuxErrorsWEn; |
next_tempUSBEndPTransTypeReg <= tempUSBEndPTransTypeReg; |
next_getPacketREn <= getPacketREn; |
next_sendPacketWEn <= sendPacketWEn; |
next_sendPacketPID <= sendPacketPID; |
next_USBEndPTransTypeReg <= USBEndPTransTypeReg; |
next_USBEndPNakTransTypeReg <= USBEndPNakTransTypeReg; |
next_endpCRCTemp <= endpCRCTemp; |
next_addrEndPTemp <= addrEndPTemp; |
next_frameNum <= frameNum; |
next_USBAddress <= USBAddress; |
next_USBEndP <= USBEndP; |
next_USBEndPControlRegCopy <= USBEndPControlRegCopy; |
next_endPointReadyToGetPkt <= endPointReadyToGetPkt; |
case (CurrState_slvCntrl) |
`WAIT_RX1: |
begin |
next_stallSent <= 1'b0; |
next_NAKSent <= 1'b0; |
next_SOFRxed <= 1'b0; |
if (RxDataWEn == 1'b1 && |
RxStatus == `RX_PACKET_START && |
RxByte[1:0] == `TOKEN) |
begin |
NextState_slvCntrl <= `GET_TOKEN_WAIT_ADDR; |
next_PIDByte <= RxByte; |
end |
end |
`FIN_SC: |
begin |
next_transDone <= 1'b0; |
next_clrEPRdy <= 1'b0; |
next_endPMuxErrorsWEn <= 1'b0; |
NextState_slvCntrl <= `WAIT_RX1; |
end |
`CHK_PID: |
if (PIDByte[3:0] == `SETUP) |
begin |
NextState_slvCntrl <= `SETUP_OUT_GET_PKT; |
next_tempUSBEndPTransTypeReg <= `SC_SETUP_TRANS; |
next_getPacketREn <= 1'b1; |
end |
else if (PIDByte[3:0] == `OUT) |
begin |
NextState_slvCntrl <= `SETUP_OUT_GET_PKT; |
next_tempUSBEndPTransTypeReg <= `SC_OUTDATA_TRANS; |
next_getPacketREn <= 1'b1; |
end |
else if ((PIDByte[3:0] == `IN) && (USBEndPControlRegCopy[`ENDPOINT_ISO_ENABLE_BIT] == 1'b0)) |
begin |
NextState_slvCntrl <= `IN_CHK_RDY; |
next_tempUSBEndPTransTypeReg <= `SC_IN_TRANS; |
end |
else if (((PIDByte[3:0] == `IN) && (USBEndPControlRegCopy [`ENDPOINT_READY_BIT] == 1'b1)) && (USBEndPControlRegCopy [`ENDPOINT_OUTDATA_SEQUENCE_BIT] == 1'b0)) |
begin |
NextState_slvCntrl <= `IN_RESP_DATA; |
next_tempUSBEndPTransTypeReg <= `SC_IN_TRANS; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `DATA0; |
end |
else if ((PIDByte[3:0] == `IN) && (USBEndPControlRegCopy [`ENDPOINT_READY_BIT] == 1'b1)) |
begin |
NextState_slvCntrl <= `IN_RESP_DATA; |
next_tempUSBEndPTransTypeReg <= `SC_IN_TRANS; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `DATA1; |
end |
else if (PIDByte[3:0] == `IN) |
begin |
NextState_slvCntrl <= `CHK_RDY; |
next_tempUSBEndPTransTypeReg <= `SC_IN_TRANS; |
end |
else |
NextState_slvCntrl <= `PID_ERROR; |
`PID_ERROR: |
NextState_slvCntrl <= `WAIT_RX1; |
`CHK_RDY: |
if (USBEndPControlRegCopy [`ENDPOINT_READY_BIT] == 1'b1) |
begin |
NextState_slvCntrl <= `FIN_SC; |
next_transDone <= 1'b1; |
next_clrEPRdy <= 1'b1; |
next_USBEndPTransTypeReg <= tempUSBEndPTransTypeReg; |
next_endPMuxErrorsWEn <= 1'b1; |
end |
else if (NAKSent == 1'b1) |
begin |
NextState_slvCntrl <= `FIN_SC; |
next_USBEndPNakTransTypeReg <= tempUSBEndPTransTypeReg; |
next_endPMuxErrorsWEn <= 1'b1; |
end |
else |
NextState_slvCntrl <= `FIN_SC; |
`SETUP_OUT_CHK: |
if (USBEndPControlRegCopy [`ENDPOINT_READY_BIT] == 1'b0) |
begin |
NextState_slvCntrl <= `SETUP_OUT_SEND; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `NAK; |
next_NAKSent <= 1'b1; |
end |
else if (USBEndPControlRegCopy [`ENDPOINT_SEND_STALL_BIT] == 1'b1) |
begin |
NextState_slvCntrl <= `SETUP_OUT_SEND; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `STALL; |
next_stallSent <= 1'b1; |
end |
else |
begin |
NextState_slvCntrl <= `SETUP_OUT_SEND; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `ACK; |
end |
`SETUP_OUT_SEND: |
begin |
next_sendPacketWEn <= 1'b0; |
if (sendPacketRdy == 1'b1) |
NextState_slvCntrl <= `CHK_RDY; |
end |
`SETUP_OUT_GET_PKT: |
begin |
next_getPacketREn <= 1'b0; |
if ((getPacketRdy == 1'b1) && (USBEndPControlRegCopy [`ENDPOINT_ISO_ENABLE_BIT] == 1'b1)) |
NextState_slvCntrl <= `CHK_RDY; |
else if ((getPacketRdy == 1'b1) && (CRCError == 1'b0 && |
bitStuffError == 1'b0 && |
RxOverflow == 1'b0 && |
RxTimeOut == 1'b0)) |
NextState_slvCntrl <= `SETUP_OUT_CHK; |
else if (getPacketRdy == 1'b1) |
NextState_slvCntrl <= `CHK_RDY; |
end |
`IN_NAK_STALL: |
begin |
next_sendPacketWEn <= 1'b0; |
if (sendPacketRdy == 1'b1) |
NextState_slvCntrl <= `CHK_RDY; |
end |
`IN_CHK_RDY: |
if (USBEndPControlRegCopy [`ENDPOINT_READY_BIT] == 1'b0) |
begin |
NextState_slvCntrl <= `IN_NAK_STALL; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `NAK; |
next_NAKSent <= 1'b1; |
end |
else if (USBEndPControlRegCopy [`ENDPOINT_SEND_STALL_BIT] == 1'b1) |
begin |
NextState_slvCntrl <= `IN_NAK_STALL; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `STALL; |
next_stallSent <= 1'b1; |
end |
else if (USBEndPControlRegCopy [`ENDPOINT_OUTDATA_SEQUENCE_BIT] == 1'b0) |
begin |
NextState_slvCntrl <= `IN_RESP_DATA; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `DATA0; |
end |
else |
begin |
NextState_slvCntrl <= `IN_RESP_DATA; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `DATA1; |
end |
`IN_RESP_GET_RESP: |
begin |
next_getPacketREn <= 1'b0; |
if (getPacketRdy == 1'b1) |
NextState_slvCntrl <= `CHK_RDY; |
end |
`IN_RESP_DATA: |
begin |
next_sendPacketWEn <= 1'b0; |
if (sendPacketRdy == 1'b1) |
NextState_slvCntrl <= `IN_RESP_CHK_ISO; |
end |
`IN_RESP_CHK_ISO: |
if (USBEndPControlRegCopy [`ENDPOINT_ISO_ENABLE_BIT] == 1'b1) |
NextState_slvCntrl <= `CHK_RDY; |
else |
begin |
NextState_slvCntrl <= `IN_RESP_GET_RESP; |
next_getPacketREn <= 1'b1; |
end |
`START_S1: |
NextState_slvCntrl <= `WAIT_RX1; |
`GET_TOKEN_WAIT_CRC: |
if (RxDataWEn == 1'b1 && |
RxStatus == `RX_PACKET_STREAM) |
begin |
NextState_slvCntrl <= `GET_TOKEN_WAIT_STOP; |
next_endpCRCTemp <= RxByte; |
end |
else if (RxDataWEn == 1'b1 && |
RxStatus != `RX_PACKET_STREAM) |
NextState_slvCntrl <= `WAIT_RX1; |
`GET_TOKEN_WAIT_ADDR: |
if (RxDataWEn == 1'b1 && |
RxStatus == `RX_PACKET_STREAM) |
begin |
NextState_slvCntrl <= `GET_TOKEN_WAIT_CRC; |
next_addrEndPTemp <= RxByte; |
end |
else if (RxDataWEn == 1'b1 && |
RxStatus != `RX_PACKET_STREAM) |
NextState_slvCntrl <= `WAIT_RX1; |
`GET_TOKEN_WAIT_STOP: |
if ((RxDataWEn == 1'b1) && (RxByte[`CRC_ERROR_BIT] == 1'b0 && |
RxByte[`BIT_STUFF_ERROR_BIT] == 1'b0 && |
RxByte [`RX_OVERFLOW_BIT] == 1'b0)) |
NextState_slvCntrl <= `GET_TOKEN_CHK_SOF; |
else if (RxDataWEn == 1'b1) |
NextState_slvCntrl <= `WAIT_RX1; |
`GET_TOKEN_CHK_SOF: |
if (PIDByte[3:0] == `SOF) |
begin |
NextState_slvCntrl <= `WAIT_RX1; |
next_frameNum <= {endpCRCTemp[2:0],addrEndPTemp}; |
next_SOFRxed <= 1'b1; |
end |
else |
begin |
NextState_slvCntrl <= `GET_TOKEN_DELAY; |
next_USBAddress <= addrEndPTemp[6:0]; |
next_USBEndP <= { endpCRCTemp[2:0], addrEndPTemp[7]}; |
end |
`GET_TOKEN_DELAY: // Insert delay to allow USBEndP etc to update |
NextState_slvCntrl <= `GET_TOKEN_CHK_ADDR; |
`GET_TOKEN_CHK_ADDR: |
if (USBEndP < `NUM_OF_ENDPOINTS && |
USBAddress == USBTgtAddress && |
SCGlobalEn == 1'b1 && |
USBEndPControlReg[`ENDPOINT_ENABLE_BIT] == 1'b1) |
begin |
NextState_slvCntrl <= `CHK_PID; |
next_USBEndPControlRegCopy <= USBEndPControlReg; |
next_endPointReadyToGetPkt <= USBEndPControlReg [`ENDPOINT_READY_BIT]; |
end |
else |
NextState_slvCntrl <= `WAIT_RX1; |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : slvCntrl_CurrentState |
if (rst) |
CurrState_slvCntrl <= `START_S1; |
else |
CurrState_slvCntrl <= NextState_slvCntrl; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : slvCntrl_RegOutput |
if (rst) |
begin |
tempUSBEndPTransTypeReg <= 2'b00; |
addrEndPTemp <= 8'h00; |
endpCRCTemp <= 8'h00; |
USBAddress <= 7'b0000000; |
PIDByte <= 8'h00; |
USBEndPControlRegCopy <= 5'b00000; |
transDone <= 1'b0; |
getPacketREn <= 1'b0; |
sendPacketPID <= 4'b0; |
sendPacketWEn <= 1'b0; |
clrEPRdy <= 1'b0; |
USBEndPTransTypeReg <= 2'b00; |
USBEndPNakTransTypeReg <= 2'b00; |
NAKSent <= 1'b0; |
stallSent <= 1'b0; |
SOFRxed <= 1'b0; |
endPMuxErrorsWEn <= 1'b0; |
frameNum <= 11'b00000000000; |
USBEndP <= 4'h0; |
endPointReadyToGetPkt <= 1'b0; |
end |
else |
begin |
tempUSBEndPTransTypeReg <= next_tempUSBEndPTransTypeReg; |
addrEndPTemp <= next_addrEndPTemp; |
endpCRCTemp <= next_endpCRCTemp; |
USBAddress <= next_USBAddress; |
PIDByte <= next_PIDByte; |
USBEndPControlRegCopy <= next_USBEndPControlRegCopy; |
transDone <= next_transDone; |
getPacketREn <= next_getPacketREn; |
sendPacketPID <= next_sendPacketPID; |
sendPacketWEn <= next_sendPacketWEn; |
clrEPRdy <= next_clrEPRdy; |
USBEndPTransTypeReg <= next_USBEndPTransTypeReg; |
USBEndPNakTransTypeReg <= next_USBEndPNakTransTypeReg; |
NAKSent <= next_NAKSent; |
stallSent <= next_stallSent; |
SOFRxed <= next_SOFRxed; |
endPMuxErrorsWEn <= next_endPMuxErrorsWEn; |
frameNum <= next_frameNum; |
USBEndP <= next_USBEndP; |
endPointReadyToGetPkt <= next_endPointReadyToGetPkt; |
end |
end |
|
endmodule |
/verilog/usbhostslave/sendPacket.v
0,0 → 1,345
|
// File : ../RTL/hostController/sendpacket.v |
// Generated : 11/10/06 05:37:20 |
// From : ../RTL/hostController/sendpacket.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// sendPacket |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
`include "usbhostslave_constants_h.v" |
|
|
|
module sendPacket (HCTxPortCntl, HCTxPortData, HCTxPortGnt, HCTxPortRdy, HCTxPortReq, HCTxPortWEn, PID, TxAddr, TxEndP, clk, fifoData, fifoEmpty, fifoReadEn, frameNum, fullSpeedPolarity, rst, sendPacketRdy, sendPacketWEn); |
input HCTxPortGnt; |
input HCTxPortRdy; |
input [3:0] PID; |
input [6:0] TxAddr; |
input [3:0] TxEndP; |
input clk; |
input [7:0] fifoData; |
input fifoEmpty; |
input fullSpeedPolarity; |
input rst; |
input sendPacketWEn; |
output [7:0] HCTxPortCntl; |
output [7:0] HCTxPortData; |
output HCTxPortReq; |
output HCTxPortWEn; |
output fifoReadEn; |
output [10:0] frameNum; |
output sendPacketRdy; |
|
reg [7:0] HCTxPortCntl, next_HCTxPortCntl; |
reg [7:0] HCTxPortData, next_HCTxPortData; |
wire HCTxPortGnt; |
wire HCTxPortRdy; |
reg HCTxPortReq, next_HCTxPortReq; |
reg HCTxPortWEn, next_HCTxPortWEn; |
wire [3:0] PID; |
wire [6:0] TxAddr; |
wire [3:0] TxEndP; |
wire clk; |
wire [7:0] fifoData; |
wire fifoEmpty; |
reg fifoReadEn, next_fifoReadEn; |
reg [10:0] frameNum, next_frameNum; |
wire fullSpeedPolarity; |
wire rst; |
reg sendPacketRdy, next_sendPacketRdy; |
wire sendPacketWEn; |
|
// diagram signals declarations |
reg [7:0]PIDNotPID; |
|
// BINARY ENCODED state machine: sndPkt |
// State codes definitions: |
`define START_SP 5'b00000 |
`define WAIT_ENABLE 5'b00001 |
`define SP_WAIT_GNT 5'b00010 |
`define SEND_PID_WAIT_RDY 5'b00011 |
`define SEND_PID_FIN 5'b00100 |
`define FIN_SP 5'b00101 |
`define OUT_IN_SETUP_WAIT_RDY1 5'b00110 |
`define OUT_IN_SETUP_WAIT_RDY2 5'b00111 |
`define OUT_IN_SETUP_FIN 5'b01000 |
`define SEND_SOF_FIN1 5'b01001 |
`define SEND_SOF_WAIT_RDY3 5'b01010 |
`define SEND_SOF_WAIT_RDY4 5'b01011 |
`define DATA0_DATA1_READ_FIFO 5'b01100 |
`define DATA0_DATA1_WAIT_READ_FIFO 5'b01101 |
`define DATA0_DATA1_FIFO_EMPTY 5'b01110 |
`define DATA0_DATA1_FIN 5'b01111 |
`define DATA0_DATA1_TERM_BYTE 5'b10000 |
`define OUT_IN_SETUP_CLR_WEN1 5'b10001 |
`define SEND_SOF_CLR_WEN1 5'b10010 |
`define DATA0_DATA1_CLR_WEN 5'b10011 |
`define DATA0_DATA1_CLR_REN 5'b10100 |
`define LS_EOP_WAIT_RDY 5'b10101 |
`define LS_EOP_FIN 5'b10110 |
|
reg [4:0] CurrState_sndPkt; |
reg [4:0] NextState_sndPkt; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
always @(PID) |
begin |
PIDNotPID <= { (PID ^ 4'hf), PID }; |
end |
|
//-------------------------------------------------------------------- |
// Machine: sndPkt |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (PIDNotPID or TxEndP or TxAddr or frameNum or fifoData or sendPacketWEn or HCTxPortGnt or PID or fullSpeedPolarity or HCTxPortRdy or fifoEmpty or sendPacketRdy or HCTxPortReq or HCTxPortWEn or HCTxPortData or HCTxPortCntl or fifoReadEn or CurrState_sndPkt) |
begin : sndPkt_NextState |
NextState_sndPkt <= CurrState_sndPkt; |
// Set default values for outputs and signals |
next_sendPacketRdy <= sendPacketRdy; |
next_HCTxPortReq <= HCTxPortReq; |
next_HCTxPortWEn <= HCTxPortWEn; |
next_HCTxPortData <= HCTxPortData; |
next_HCTxPortCntl <= HCTxPortCntl; |
next_frameNum <= frameNum; |
next_fifoReadEn <= fifoReadEn; |
case (CurrState_sndPkt) |
`START_SP: |
NextState_sndPkt <= `WAIT_ENABLE; |
`WAIT_ENABLE: |
if (sendPacketWEn == 1'b1) |
begin |
NextState_sndPkt <= `SP_WAIT_GNT; |
next_sendPacketRdy <= 1'b0; |
next_HCTxPortReq <= 1'b1; |
end |
`SP_WAIT_GNT: |
if ((HCTxPortGnt == 1'b1) && (PID == `SOF && fullSpeedPolarity == 1'b0)) |
NextState_sndPkt <= `LS_EOP_WAIT_RDY; |
else if (HCTxPortGnt == 1'b1) |
NextState_sndPkt <= `SEND_PID_WAIT_RDY; |
`FIN_SP: |
begin |
NextState_sndPkt <= `WAIT_ENABLE; |
next_sendPacketRdy <= 1'b1; |
next_HCTxPortReq <= 1'b0; |
end |
`SEND_PID_WAIT_RDY: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sndPkt <= `SEND_PID_FIN; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= PIDNotPID; |
next_HCTxPortCntl <= `TX_PACKET_START; |
end |
`SEND_PID_FIN: |
begin |
next_HCTxPortWEn <= 1'b0; |
if (PID == `DATA0 || PID == `DATA1) |
NextState_sndPkt <= `DATA0_DATA1_FIFO_EMPTY; |
else if (PID == `SOF) |
NextState_sndPkt <= `SEND_SOF_WAIT_RDY3; |
else if (PID == `OUT || |
PID == `IN || |
PID == `SETUP) |
NextState_sndPkt <= `OUT_IN_SETUP_WAIT_RDY1; |
else |
NextState_sndPkt <= `FIN_SP; |
end |
`OUT_IN_SETUP_WAIT_RDY1: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sndPkt <= `OUT_IN_SETUP_CLR_WEN1; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= {TxEndP[0], TxAddr[6:0]}; |
next_HCTxPortCntl <= `TX_PACKET_STREAM; |
end |
`OUT_IN_SETUP_WAIT_RDY2: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sndPkt <= `OUT_IN_SETUP_FIN; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= {5'b00000, TxEndP[3:1]}; |
next_HCTxPortCntl <= `TX_PACKET_STREAM; |
end |
`OUT_IN_SETUP_FIN: |
begin |
next_HCTxPortWEn <= 1'b0; |
NextState_sndPkt <= `FIN_SP; |
end |
`OUT_IN_SETUP_CLR_WEN1: |
begin |
next_HCTxPortWEn <= 1'b0; |
NextState_sndPkt <= `OUT_IN_SETUP_WAIT_RDY2; |
end |
`SEND_SOF_FIN1: |
begin |
next_HCTxPortWEn <= 1'b0; |
next_frameNum <= frameNum + 1'b1; |
NextState_sndPkt <= `FIN_SP; |
end |
`SEND_SOF_WAIT_RDY3: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sndPkt <= `SEND_SOF_CLR_WEN1; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= frameNum[7:0]; |
next_HCTxPortCntl <= `TX_PACKET_STREAM; |
end |
`SEND_SOF_WAIT_RDY4: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sndPkt <= `SEND_SOF_FIN1; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= {5'b00000, frameNum[10:8]}; |
next_HCTxPortCntl <= `TX_PACKET_STREAM; |
end |
`SEND_SOF_CLR_WEN1: |
begin |
next_HCTxPortWEn <= 1'b0; |
NextState_sndPkt <= `SEND_SOF_WAIT_RDY4; |
end |
`DATA0_DATA1_READ_FIFO: |
begin |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= fifoData; |
next_HCTxPortCntl <= `TX_PACKET_STREAM; |
NextState_sndPkt <= `DATA0_DATA1_CLR_WEN; |
end |
`DATA0_DATA1_WAIT_READ_FIFO: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sndPkt <= `DATA0_DATA1_CLR_REN; |
next_fifoReadEn <= 1'b1; |
end |
`DATA0_DATA1_FIFO_EMPTY: |
if (fifoEmpty == 1'b0) |
NextState_sndPkt <= `DATA0_DATA1_WAIT_READ_FIFO; |
else |
NextState_sndPkt <= `DATA0_DATA1_TERM_BYTE; |
`DATA0_DATA1_FIN: |
begin |
next_HCTxPortWEn <= 1'b0; |
NextState_sndPkt <= `FIN_SP; |
end |
`DATA0_DATA1_TERM_BYTE: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sndPkt <= `DATA0_DATA1_FIN; |
//Last byte is not valid data, |
//but the 'TX_PACKET_STOP' flag is required |
//by the SIE state machine to detect end of data packet |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= 8'h00; |
next_HCTxPortCntl <= `TX_PACKET_STOP; |
end |
`DATA0_DATA1_CLR_WEN: |
begin |
next_HCTxPortWEn <= 1'b0; |
NextState_sndPkt <= `DATA0_DATA1_FIFO_EMPTY; |
end |
`DATA0_DATA1_CLR_REN: |
begin |
next_fifoReadEn <= 1'b0; |
NextState_sndPkt <= `DATA0_DATA1_READ_FIFO; |
end |
`LS_EOP_WAIT_RDY: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sndPkt <= `LS_EOP_FIN; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= 8'h00; |
next_HCTxPortCntl <= `TX_LS_KEEP_ALIVE; |
end |
`LS_EOP_FIN: |
begin |
next_HCTxPortWEn <= 1'b0; |
NextState_sndPkt <= `FIN_SP; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : sndPkt_CurrentState |
if (rst) |
CurrState_sndPkt <= `START_SP; |
else |
CurrState_sndPkt <= NextState_sndPkt; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : sndPkt_RegOutput |
if (rst) |
begin |
sendPacketRdy <= 1'b1; |
HCTxPortReq <= 1'b0; |
HCTxPortWEn <= 1'b0; |
HCTxPortData <= 8'h00; |
HCTxPortCntl <= 8'h00; |
frameNum <= 11'h000; |
fifoReadEn <= 1'b0; |
end |
else |
begin |
sendPacketRdy <= next_sendPacketRdy; |
HCTxPortReq <= next_HCTxPortReq; |
HCTxPortWEn <= next_HCTxPortWEn; |
HCTxPortData <= next_HCTxPortData; |
HCTxPortCntl <= next_HCTxPortCntl; |
frameNum <= next_frameNum; |
fifoReadEn <= next_fifoReadEn; |
end |
end |
|
endmodule |
/verilog/usbhostslave/hostcontroller.v
0,0 → 1,386
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// hostController |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_hostcontrol_h.v" |
`include "usbhostslave_constants_h.v" |
|
|
module hostcontroller (RXStatus, clearTXReq, clk, getPacketREn, getPacketRdy, isoEn, rst, sendPacketArbiterGnt, sendPacketArbiterReq, sendPacketPID, sendPacketRdy, sendPacketWEn, transDone, transReq, transType); |
input [7:0] RXStatus; |
input clk; |
input getPacketRdy; |
input isoEn; |
input rst; |
input sendPacketArbiterGnt; |
input sendPacketRdy; |
input transReq; |
input [1:0] transType; |
output clearTXReq; |
output getPacketREn; |
output sendPacketArbiterReq; |
output [3:0] sendPacketPID; |
output sendPacketWEn; |
output transDone; |
|
wire [7:0] RXStatus; |
reg clearTXReq, next_clearTXReq; |
wire clk; |
reg getPacketREn, next_getPacketREn; |
wire getPacketRdy; |
wire isoEn; |
wire rst; |
wire sendPacketArbiterGnt; |
reg sendPacketArbiterReq, next_sendPacketArbiterReq; |
reg [3:0] sendPacketPID, next_sendPacketPID; |
wire sendPacketRdy; |
reg sendPacketWEn, next_sendPacketWEn; |
reg transDone, next_transDone; |
wire transReq; |
wire [1:0] transType; |
|
// diagram signals declarations |
reg [3:0]delCnt, next_delCnt; |
|
// BINARY ENCODED state machine: hstCntrl |
// State codes definitions: |
`define START_HC 6'b000000 |
`define TX_REQ 6'b000001 |
`define CHK_TYPE 6'b000010 |
`define FLAG 6'b000011 |
`define IN_WAIT_DATA_RXED 6'b000100 |
`define IN_CHK_FOR_ERROR 6'b000101 |
`define IN_CLR_SP_WEN2 6'b000110 |
`define SETUP_CLR_SP_WEN1 6'b000111 |
`define SETUP_CLR_SP_WEN2 6'b001000 |
`define FIN 6'b001001 |
`define WAIT_GNT 6'b001010 |
`define SETUP_WAIT_PKT_RXED 6'b001011 |
`define IN_WAIT_IN_SENT 6'b001100 |
`define OUT0_WAIT_RX_DATA 6'b001101 |
`define OUT0_WAIT_DATA0_SENT 6'b001110 |
`define OUT0_WAIT_OUT_SENT 6'b001111 |
`define SETUP_HC_WAIT_RDY 6'b010000 |
`define IN_WAIT_SP_RDY1 6'b010001 |
`define IN_WAIT_SP_RDY2 6'b010010 |
`define OUT0_WAIT_SP_RDY1 6'b010011 |
`define SETUP_WAIT_SETUP_SENT 6'b010100 |
`define SETUP_WAIT_DATA_SENT 6'b010101 |
`define IN_CLR_SP_WEN1 6'b010110 |
`define IN_WAIT_ACK_SENT 6'b010111 |
`define OUT0_CLR_WEN1 6'b011000 |
`define OUT0_CLR_WEN2 6'b011001 |
`define OUT1_WAIT_RX_DATA 6'b011010 |
`define OUT1_WAIT_OUT_SENT 6'b011011 |
`define OUT1_WAIT_DATA1_SENT 6'b011100 |
`define OUT1_WAIT_SP_RDY1 6'b011101 |
`define OUT1_CLR_WEN1 6'b011110 |
`define OUT1_CLR_WEN2 6'b011111 |
`define OUT0_CHK_ISO 6'b100000 |
|
reg [5:0] CurrState_hstCntrl; |
reg [5:0] NextState_hstCntrl; |
|
|
//-------------------------------------------------------------------- |
// Machine: hstCntrl |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (delCnt or transReq or transType or sendPacketArbiterGnt or getPacketRdy or sendPacketRdy or isoEn or RXStatus or sendPacketArbiterReq or transDone or clearTXReq or sendPacketWEn or getPacketREn or sendPacketPID or CurrState_hstCntrl) |
begin : hstCntrl_NextState |
NextState_hstCntrl <= CurrState_hstCntrl; |
// Set default values for outputs and signals |
next_sendPacketArbiterReq <= sendPacketArbiterReq; |
next_transDone <= transDone; |
next_clearTXReq <= clearTXReq; |
next_delCnt <= delCnt; |
next_sendPacketWEn <= sendPacketWEn; |
next_getPacketREn <= getPacketREn; |
next_sendPacketPID <= sendPacketPID; |
case (CurrState_hstCntrl) // synopsys parallel_case full_case |
`START_HC: |
NextState_hstCntrl <= `TX_REQ; |
`TX_REQ: |
if (transReq == 1'b1) |
begin |
NextState_hstCntrl <= `WAIT_GNT; |
next_sendPacketArbiterReq <= 1'b1; |
end |
`CHK_TYPE: |
if (transType == `IN_TRANS) |
NextState_hstCntrl <= `IN_WAIT_SP_RDY1; |
else if (transType == `OUTDATA0_TRANS) |
NextState_hstCntrl <= `OUT0_WAIT_SP_RDY1; |
else if (transType == `OUTDATA1_TRANS) |
NextState_hstCntrl <= `OUT1_WAIT_SP_RDY1; |
else if (transType == `SETUP_TRANS) |
NextState_hstCntrl <= `SETUP_HC_WAIT_RDY; |
`FLAG: |
begin |
next_transDone <= 1'b1; |
next_clearTXReq <= 1'b1; |
next_sendPacketArbiterReq <= 1'b0; |
next_delCnt <= 4'h0; |
NextState_hstCntrl <= `FIN; |
end |
`FIN: |
begin |
next_clearTXReq <= 1'b0; |
next_transDone <= 1'b0; |
next_delCnt <= delCnt + 1'b1; |
//now wait for 'transReq' to clear |
if (delCnt == 4'hf) |
NextState_hstCntrl <= `TX_REQ; |
end |
`WAIT_GNT: |
if (sendPacketArbiterGnt == 1'b1) |
NextState_hstCntrl <= `CHK_TYPE; |
`SETUP_CLR_SP_WEN1: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_hstCntrl <= `SETUP_WAIT_SETUP_SENT; |
end |
`SETUP_CLR_SP_WEN2: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_hstCntrl <= `SETUP_WAIT_DATA_SENT; |
end |
`SETUP_WAIT_PKT_RXED: |
begin |
next_getPacketREn <= 1'b0; |
if (getPacketRdy == 1'b1) |
NextState_hstCntrl <= `FLAG; |
end |
`SETUP_HC_WAIT_RDY: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `SETUP_CLR_SP_WEN1; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `SETUP; |
end |
`SETUP_WAIT_SETUP_SENT: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `SETUP_CLR_SP_WEN2; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `DATA0; |
end |
`SETUP_WAIT_DATA_SENT: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `SETUP_WAIT_PKT_RXED; |
next_getPacketREn <= 1'b1; |
end |
`IN_WAIT_DATA_RXED: |
begin |
next_getPacketREn <= 1'b0; |
if (getPacketRdy == 1'b1) |
NextState_hstCntrl <= `IN_CHK_FOR_ERROR; |
end |
`IN_CHK_FOR_ERROR: |
if (isoEn == 1'b1) |
NextState_hstCntrl <= `FLAG; |
else if (RXStatus [`HC_CRC_ERROR_BIT] == 1'b0 && |
RXStatus [`HC_BIT_STUFF_ERROR_BIT] == 1'b0 && |
RXStatus [`HC_RX_OVERFLOW_BIT] == 1'b0 && |
RXStatus [`HC_NAK_RXED_BIT] == 1'b0 && |
RXStatus [`HC_STALL_RXED_BIT] == 1'b0 && |
RXStatus [`HC_RX_TIME_OUT_BIT] == 1'b0) |
NextState_hstCntrl <= `IN_WAIT_SP_RDY2; |
else |
NextState_hstCntrl <= `FLAG; |
`IN_CLR_SP_WEN2: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_hstCntrl <= `IN_WAIT_ACK_SENT; |
end |
`IN_WAIT_IN_SENT: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `IN_WAIT_DATA_RXED; |
next_getPacketREn <= 1'b1; |
end |
`IN_WAIT_SP_RDY1: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `IN_CLR_SP_WEN1; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `IN; |
end |
`IN_WAIT_SP_RDY2: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `IN_CLR_SP_WEN2; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `ACK; |
end |
`IN_CLR_SP_WEN1: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_hstCntrl <= `IN_WAIT_IN_SENT; |
end |
`IN_WAIT_ACK_SENT: |
if (sendPacketRdy == 1'b1) |
NextState_hstCntrl <= `FLAG; |
`OUT0_WAIT_RX_DATA: |
begin |
next_getPacketREn <= 1'b0; |
if (getPacketRdy == 1'b1) |
NextState_hstCntrl <= `FLAG; |
end |
`OUT0_WAIT_DATA0_SENT: |
if (sendPacketRdy == 1'b1) |
NextState_hstCntrl <= `OUT0_CHK_ISO; |
`OUT0_WAIT_OUT_SENT: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `OUT0_CLR_WEN2; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `DATA0; |
end |
`OUT0_WAIT_SP_RDY1: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `OUT0_CLR_WEN1; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `OUT; |
end |
`OUT0_CLR_WEN1: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_hstCntrl <= `OUT0_WAIT_OUT_SENT; |
end |
`OUT0_CLR_WEN2: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_hstCntrl <= `OUT0_WAIT_DATA0_SENT; |
end |
`OUT0_CHK_ISO: |
if (isoEn == 1'b0) |
begin |
NextState_hstCntrl <= `OUT0_WAIT_RX_DATA; |
next_getPacketREn <= 1'b1; |
end |
else |
NextState_hstCntrl <= `FLAG; |
`OUT1_WAIT_RX_DATA: |
begin |
next_getPacketREn <= 1'b0; |
if (getPacketRdy == 1'b1) |
NextState_hstCntrl <= `FLAG; |
end |
`OUT1_WAIT_OUT_SENT: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `OUT1_CLR_WEN2; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `DATA1; |
end |
`OUT1_WAIT_DATA1_SENT: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `OUT1_WAIT_RX_DATA; |
next_getPacketREn <= 1'b1; |
end |
`OUT1_WAIT_SP_RDY1: |
if (sendPacketRdy == 1'b1) |
begin |
NextState_hstCntrl <= `OUT1_CLR_WEN1; |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `OUT; |
end |
`OUT1_CLR_WEN1: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_hstCntrl <= `OUT1_WAIT_OUT_SENT; |
end |
`OUT1_CLR_WEN2: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_hstCntrl <= `OUT1_WAIT_DATA1_SENT; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : hstCntrl_CurrentState |
if (rst) |
CurrState_hstCntrl <= `START_HC; |
else |
CurrState_hstCntrl <= NextState_hstCntrl; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : hstCntrl_RegOutput |
if (rst) |
begin |
delCnt <= 4'h0; |
transDone <= 1'b0; |
clearTXReq <= 1'b0; |
getPacketREn <= 1'b0; |
sendPacketArbiterReq <= 1'b0; |
sendPacketWEn <= 1'b0; |
sendPacketPID <= 4'b0; |
end |
else |
begin |
delCnt <= next_delCnt; |
transDone <= next_transDone; |
clearTXReq <= next_clearTXReq; |
getPacketREn <= next_getPacketREn; |
sendPacketArbiterReq <= next_sendPacketArbiterReq; |
sendPacketWEn <= next_sendPacketWEn; |
sendPacketPID <= next_sendPacketPID; |
end |
end |
|
endmodule |
/verilog/usbhostslave/updateCRC16.v
0,0 → 1,105
////////////////////////////////////////////////////////////////////// |
//// //// |
//// updateCRC16.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module updateCRC16 (rstCRC, CRCResult, CRCEn, dataIn, ready, clk, rst); |
input rstCRC; |
input CRCEn; |
input [7:0] dataIn; |
input clk; |
input rst; |
output [15:0] CRCResult; |
output ready; |
|
wire rstCRC; |
wire CRCEn; |
wire [7:0] dataIn; |
wire clk; |
wire rst; |
reg [15:0] CRCResult; |
reg ready; |
|
reg doUpdateCRC; |
reg [7:0] data; |
reg [3:0] i; |
|
always @(posedge clk) |
begin |
if (rst == 1'b1 || rstCRC == 1'b1) begin |
doUpdateCRC <= 1'b0; |
i <= 4'h0; |
CRCResult <= 16'hffff; |
ready <= 1'b1; |
end |
else |
begin |
if (doUpdateCRC == 1'b0) |
begin |
if (CRCEn == 1'b1) begin |
doUpdateCRC <= 1'b1; |
data <= dataIn; |
ready <= 1'b0; |
end |
end |
else begin |
i <= i + 1'b1; |
if ( (CRCResult[0] ^ data[0]) == 1'b1) begin |
CRCResult <= {1'b0, CRCResult[15:1]} ^ 16'ha001; |
end |
else begin |
CRCResult <= {1'b0, CRCResult[15:1]}; |
end |
data <= {1'b0, data[7:1]}; |
if (i == 4'h7) |
begin |
doUpdateCRC <= 1'b0; |
i <= 4'h0; |
ready <= 1'b1; |
end |
end |
end |
end |
|
|
endmodule |
/verilog/usbhostslave/usbhostslave.v
0,0 → 1,576
////////////////////////////////////////////////////////////////////// |
//// //// |
//// usbHostSlave.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// Top level module |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module usbhostslave( // uncapitalised name -- jb |
clk_i, |
rst_i, |
address_i, |
data_i, |
data_o, |
we_i, |
strobe_i, |
ack_o, |
usbClk, |
hostSOFSentIntOut, |
hostConnEventIntOut, |
hostResumeIntOut, |
hostTransDoneIntOut, |
slaveVBusDetIntOut, |
slaveNAKSentIntOut, |
slaveSOFRxedIntOut, |
slaveResetEventIntOut, |
slaveResumeIntOut, |
slaveTransDoneIntOut, |
USBWireDataIn, |
USBWireDataInTick, |
USBWireDataOut, |
USBWireDataOutTick, |
USBWireCtrlOut, |
USBFullSpeed, |
USBDPlusPullup, |
USBDMinusPullup, |
vBusDetect |
); |
parameter HOST_FIFO_DEPTH = 64; //HOST_FIFO_DEPTH = HOST_ADDR_WIDTH^2 |
parameter HOST_FIFO_ADDR_WIDTH = 6; |
parameter EP0_FIFO_DEPTH = 64; |
parameter EP0_FIFO_ADDR_WIDTH = 6; |
parameter EP1_FIFO_DEPTH = 64; |
parameter EP1_FIFO_ADDR_WIDTH = 6; |
parameter EP2_FIFO_DEPTH = 64; |
parameter EP2_FIFO_ADDR_WIDTH = 6; |
parameter EP3_FIFO_DEPTH = 64; |
parameter EP3_FIFO_ADDR_WIDTH = 6; |
|
input clk_i; //Wishbone bus clock. Min = usbClk/2 = 24MHz. Max 5*usbClk=240MHz |
input rst_i; //Wishbone bus sync reset. Synchronous to 'clk_i'. Resets all logic |
input [7:0] address_i; //Wishbone bus address in |
input [7:0] data_i; //Wishbone bus data in |
output [7:0] data_o; //Wishbone bus data out |
input we_i; //Wishbone bus write enable in |
input strobe_i; //Wishbone bus strobe in |
output ack_o; //Wishbone bus acknowledge out |
input usbClk; //usb clock. 48Mhz +/-0.25% |
output hostSOFSentIntOut; |
output hostConnEventIntOut; |
output hostResumeIntOut; |
output hostTransDoneIntOut; |
output slaveSOFRxedIntOut; |
output slaveResetEventIntOut; |
output slaveResumeIntOut; |
output slaveTransDoneIntOut; |
output slaveNAKSentIntOut; |
output slaveVBusDetIntOut; |
input [1:0] USBWireDataIn; |
output [1:0] USBWireDataOut; |
output USBWireDataOutTick; |
output USBWireDataInTick; |
output USBWireCtrlOut; |
output USBFullSpeed; |
output USBDPlusPullup; |
output USBDMinusPullup; |
input vBusDetect; |
|
wire clk_i; |
wire rst_i; |
wire [7:0] address_i; |
wire [7:0] data_i; |
wire [7:0] data_o; |
wire we_i; |
wire strobe_i; |
wire ack_o; |
wire usbClk; |
wire hostSOFSentIntOut; |
wire hostConnEventIntOut; |
wire hostResumeIntOut; |
wire hostTransDoneIntOut; |
wire slaveSOFRxedIntOut; |
wire slaveResetEventIntOut; |
wire slaveResumeIntOut; |
wire slaveTransDoneIntOut; |
wire slaveNAKSentIntOut; |
wire slaveVBusDetIntOut; |
wire [1:0] USBWireDataIn; |
wire [1:0] USBWireDataOut; |
wire USBWireDataOutTick; |
wire USBWireDataInTick; |
wire USBWireCtrlOut; |
wire USBFullSpeed; |
wire USBDPlusPullup; |
wire USBDMinusPullup; |
wire vBusDetect; |
|
//internal wiring |
wire hostControlSel; |
wire slaveControlSel; |
wire hostRxFifoSel; |
wire hostTxFifoSel; |
wire hostSlaveMuxSel; |
wire [7:0] dataFromHostControl; |
wire [7:0] dataFromSlaveControl; |
wire [7:0] dataFromHostRxFifo; |
wire [7:0] dataFromHostTxFifo; |
wire [7:0] dataFromHostSlaveMux; |
wire hostTxFifoRE; |
wire [7:0] hostTxFifoData; |
wire hostTxFifoEmpty; |
wire hostRxFifoWE; |
wire [7:0] hostRxFifoData; |
wire hostRxFifoFull; |
wire [7:0] RxCtrlOut; |
wire [7:0] RxDataFromSIE; |
wire RxDataOutWEn; |
wire fullSpeedBitRateFromHost; |
wire fullSpeedBitRateFromSlave; |
wire fullSpeedPolarityFromHost; |
wire fullSpeedPolarityFromSlave; |
wire SIEPortWEnFromHost; |
wire SIEPortWEnFromSlave; |
wire SIEPortTxRdy; |
wire [7:0] SIEPortDataInFromHost; |
wire [7:0] SIEPortDataInFromSlave; |
wire [7:0] SIEPortCtrlInFromHost; |
wire [7:0] SIEPortCtrlInFromSlave; |
wire [1:0] connectState; |
wire resumeDetected; |
wire [7:0] SIEPortDataInToSIE; |
wire SIEPortWEnToSIE; |
wire [7:0] SIEPortCtrlInToSIE; |
wire fullSpeedPolarityToSIE; |
wire fullSpeedBitRateToSIE; |
wire noActivityTimeOut; |
wire TxFifoEP0REn; |
wire TxFifoEP1REn; |
wire TxFifoEP2REn; |
wire TxFifoEP3REn; |
wire [7:0] TxFifoEP0Data; |
wire [7:0] TxFifoEP1Data; |
wire [7:0] TxFifoEP2Data; |
wire [7:0] TxFifoEP3Data; |
wire TxFifoEP0Empty; |
wire TxFifoEP1Empty; |
wire TxFifoEP2Empty; |
wire TxFifoEP3Empty; |
wire RxFifoEP0WEn; |
wire RxFifoEP1WEn; |
wire RxFifoEP2WEn; |
wire RxFifoEP3WEn; |
wire RxFifoEP0Full; |
wire RxFifoEP1Full; |
wire RxFifoEP2Full; |
wire RxFifoEP3Full; |
wire [7:0] slaveRxFifoData; |
wire [7:0] dataFromEP0RxFifo; |
wire [7:0] dataFromEP1RxFifo; |
wire [7:0] dataFromEP2RxFifo; |
wire [7:0] dataFromEP3RxFifo; |
wire [7:0] dataFromEP0TxFifo; |
wire [7:0] dataFromEP1TxFifo; |
wire [7:0] dataFromEP2TxFifo; |
wire [7:0] dataFromEP3TxFifo; |
wire slaveEP0RxFifoSel; |
wire slaveEP1RxFifoSel; |
wire slaveEP2RxFifoSel; |
wire slaveEP3RxFifoSel; |
wire slaveEP0TxFifoSel; |
wire slaveEP1TxFifoSel; |
wire slaveEP2TxFifoSel; |
wire slaveEP3TxFifoSel; |
wire rstSyncToBusClk; |
wire rstSyncToUsbClk; |
wire noActivityTimeOutEnableToSIE; |
wire noActivityTimeOutEnableFromHost; |
wire noActivityTimeOutEnableFromSlave; |
wire connectSlaveToHost; |
|
assign USBFullSpeed = fullSpeedBitRateToSIE; |
assign USBDPlusPullup = (USBFullSpeed & connectSlaveToHost); |
assign USBDMinusPullup = (~USBFullSpeed & connectSlaveToHost); |
|
usbHostControl u_usbHostControl( |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.usbClk(usbClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.TxFifoRE(hostTxFifoRE), |
.TxFifoData(hostTxFifoData), |
.TxFifoEmpty(hostTxFifoEmpty), |
.RxFifoWE(hostRxFifoWE), |
.RxFifoData(hostRxFifoData), |
.RxFifoFull(hostRxFifoFull), |
.RxByteStatus(RxCtrlOut), |
.RxData(RxDataFromSIE), |
.RxDataValid(RxDataOutWEn), |
.SIERxTimeOut(noActivityTimeOut), |
.SIERxTimeOutEn(noActivityTimeOutEnableFromHost), |
.fullSpeedRate(fullSpeedBitRateFromHost), |
.fullSpeedPol(fullSpeedPolarityFromHost), |
.HCTxPortEn(SIEPortWEnFromHost), |
.HCTxPortRdy(SIEPortTxRdy), |
.HCTxPortData(SIEPortDataInFromHost), |
.HCTxPortCtrl(SIEPortCtrlInFromHost), |
.connectStateIn(connectState), |
.resumeDetectedIn(resumeDetected), |
.busAddress(address_i[3:0]), |
.busDataIn(data_i), |
.busDataOut(dataFromHostControl), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.SOFSentIntOut(hostSOFSentIntOut), |
.connEventIntOut(hostConnEventIntOut), |
.resumeIntOut(hostResumeIntOut), |
.transDoneIntOut(hostTransDoneIntOut), |
.hostControlSelect(hostControlSel) ); |
|
|
usbSlaveControl u_usbSlaveControl( |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.usbClk(usbClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.RxByteStatus(RxCtrlOut), |
.RxData(RxDataFromSIE), |
.RxDataValid(RxDataOutWEn), |
.SIERxTimeOut(noActivityTimeOut), |
.SIERxTimeOutEn(noActivityTimeOutEnableFromSlave), |
.RxFifoData(slaveRxFifoData), |
.connectSlaveToHost(connectSlaveToHost), |
.fullSpeedRate(fullSpeedBitRateFromSlave), |
.fullSpeedPol(fullSpeedPolarityFromSlave), |
.SCTxPortEn(SIEPortWEnFromSlave), |
.SCTxPortRdy(SIEPortTxRdy), |
.SCTxPortData(SIEPortDataInFromSlave), |
.SCTxPortCtrl(SIEPortCtrlInFromSlave), |
.vBusDetect(vBusDetect), |
.connectStateIn(connectState), |
.resumeDetectedIn(resumeDetected), |
.busAddress(address_i[4:0]), |
.busDataIn(data_i), |
.busDataOut(dataFromSlaveControl), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.SOFRxedIntOut(slaveSOFRxedIntOut), |
.resetEventIntOut(slaveResetEventIntOut), |
.resumeIntOut(slaveResumeIntOut), |
.transDoneIntOut(slaveTransDoneIntOut), |
.NAKSentIntOut(slaveNAKSentIntOut), |
.vBusDetIntOut(slaveVBusDetIntOut), |
.slaveControlSelect(slaveControlSel), |
.TxFifoEP0REn(TxFifoEP0REn), |
.TxFifoEP1REn(TxFifoEP1REn), |
.TxFifoEP2REn(TxFifoEP2REn), |
.TxFifoEP3REn(TxFifoEP3REn), |
.TxFifoEP0Data(TxFifoEP0Data), |
.TxFifoEP1Data(TxFifoEP1Data), |
.TxFifoEP2Data(TxFifoEP2Data), |
.TxFifoEP3Data(TxFifoEP3Data), |
.TxFifoEP0Empty(TxFifoEP0Empty), |
.TxFifoEP1Empty(TxFifoEP1Empty), |
.TxFifoEP2Empty(TxFifoEP2Empty), |
.TxFifoEP3Empty(TxFifoEP3Empty), |
.RxFifoEP0WEn(RxFifoEP0WEn), |
.RxFifoEP1WEn(RxFifoEP1WEn), |
.RxFifoEP2WEn(RxFifoEP2WEn), |
.RxFifoEP3WEn(RxFifoEP3WEn), |
.RxFifoEP0Full(RxFifoEP0Full), |
.RxFifoEP1Full(RxFifoEP1Full), |
.RxFifoEP2Full(RxFifoEP2Full), |
.RxFifoEP3Full(RxFifoEP3Full) |
); |
|
wishBoneBI u_wishBoneBI ( |
.address(address_i), |
.dataIn(data_i), |
.dataOut(data_o), |
.writeEn(we_i), |
.strobe_i(strobe_i), |
.ack_o(ack_o), |
.clk(clk_i), |
.rst(rstSyncToBusClk), |
.hostControlSel(hostControlSel), |
.hostRxFifoSel(hostRxFifoSel), |
.hostTxFifoSel(hostTxFifoSel), |
.slaveControlSel(slaveControlSel), |
.slaveEP0RxFifoSel(slaveEP0RxFifoSel), |
.slaveEP1RxFifoSel(slaveEP1RxFifoSel), |
.slaveEP2RxFifoSel(slaveEP2RxFifoSel), |
.slaveEP3RxFifoSel(slaveEP3RxFifoSel), |
.slaveEP0TxFifoSel(slaveEP0TxFifoSel), |
.slaveEP1TxFifoSel(slaveEP1TxFifoSel), |
.slaveEP2TxFifoSel(slaveEP2TxFifoSel), |
.slaveEP3TxFifoSel(slaveEP3TxFifoSel), |
.hostSlaveMuxSel(hostSlaveMuxSel), |
.dataFromHostControl(dataFromHostControl), |
.dataFromHostRxFifo(dataFromHostRxFifo), |
.dataFromHostTxFifo(dataFromHostTxFifo), |
.dataFromSlaveControl(dataFromSlaveControl), |
.dataFromEP0RxFifo(dataFromEP0RxFifo), |
.dataFromEP1RxFifo(dataFromEP1RxFifo), |
.dataFromEP2RxFifo(dataFromEP2RxFifo), |
.dataFromEP3RxFifo(dataFromEP3RxFifo), |
.dataFromEP0TxFifo(dataFromEP0TxFifo), |
.dataFromEP1TxFifo(dataFromEP1TxFifo), |
.dataFromEP2TxFifo(dataFromEP2TxFifo), |
.dataFromEP3TxFifo(dataFromEP3TxFifo), |
.dataFromHostSlaveMux(dataFromHostSlaveMux) |
); |
|
hostSlaveMux u_hostSlaveMux( |
.SIEPortCtrlInToSIE(SIEPortCtrlInToSIE), |
.SIEPortCtrlInFromHost(SIEPortCtrlInFromHost), |
.SIEPortCtrlInFromSlave(SIEPortCtrlInFromSlave), |
.SIEPortDataInToSIE(SIEPortDataInToSIE), |
.SIEPortDataInFromHost(SIEPortDataInFromHost), |
.SIEPortDataInFromSlave(SIEPortDataInFromSlave), |
.SIEPortWEnToSIE(SIEPortWEnToSIE), |
.SIEPortWEnFromHost(SIEPortWEnFromHost), |
.SIEPortWEnFromSlave(SIEPortWEnFromSlave), |
.fullSpeedPolarityToSIE(fullSpeedPolarityToSIE), |
.fullSpeedPolarityFromHost(fullSpeedPolarityFromHost), |
.fullSpeedPolarityFromSlave(fullSpeedPolarityFromSlave), |
.fullSpeedBitRateToSIE(fullSpeedBitRateToSIE), |
.fullSpeedBitRateFromHost(fullSpeedBitRateFromHost), |
.fullSpeedBitRateFromSlave(fullSpeedBitRateFromSlave), |
.noActivityTimeOutEnableToSIE(noActivityTimeOutEnableToSIE), |
.noActivityTimeOutEnableFromHost(noActivityTimeOutEnableFromHost), |
.noActivityTimeOutEnableFromSlave(noActivityTimeOutEnableFromSlave), |
.dataIn(data_i), |
.dataOut(dataFromHostSlaveMux), |
.address(address_i[0]), |
.writeEn(we_i), |
.strobe_i(strobe_i), |
.usbClk(usbClk), |
.busClk(clk_i), |
.hostSlaveMuxSel(hostSlaveMuxSel), |
.rstFromWire(rst_i), |
.rstSyncToBusClkOut(rstSyncToBusClk), |
.rstSyncToUsbClkOut(rstSyncToUsbClk) |
); |
|
usbSerialInterfaceEngine u_usbSerialInterfaceEngine( |
.clk(usbClk), |
.rst(rstSyncToUsbClk), |
.USBWireDataIn(USBWireDataIn), |
.USBWireDataOut(USBWireDataOut), |
.USBWireDataInTick(USBWireDataInTick), |
.USBWireDataOutTick(USBWireDataOutTick), |
.USBWireCtrlOut(USBWireCtrlOut), |
.connectState(connectState), |
.resumeDetected(resumeDetected), |
.RxCtrlOut(RxCtrlOut), |
.RxDataOutWEn(RxDataOutWEn), |
.RxDataOut(RxDataFromSIE), |
.SIEPortCtrlIn(SIEPortCtrlInToSIE), |
.SIEPortDataIn(SIEPortDataInToSIE), |
.SIEPortTxRdy(SIEPortTxRdy), |
.SIEPortWEn(SIEPortWEnToSIE), |
.fullSpeedPolarity(fullSpeedPolarityToSIE), |
.fullSpeedBitRate(fullSpeedBitRateToSIE), |
.noActivityTimeOut(noActivityTimeOut), |
.noActivityTimeOutEnable(noActivityTimeOutEnableToSIE) |
); |
|
//---Host fifos |
TxFifo #(HOST_FIFO_DEPTH, HOST_FIFO_ADDR_WIDTH) HostTxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(hostTxFifoRE), |
.fifoEmpty(hostTxFifoEmpty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(hostTxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromHostTxFifo), |
.fifoDataOut(hostTxFifoData) ); |
|
|
RxFifo #(HOST_FIFO_DEPTH, HOST_FIFO_ADDR_WIDTH) HostRxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(hostRxFifoWE), |
.fifoFull(hostRxFifoFull), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(hostRxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromHostRxFifo), |
.fifoDataIn(hostRxFifoData) ); |
|
//---Slave fifos |
|
TxFifo #(EP0_FIFO_DEPTH, EP0_FIFO_ADDR_WIDTH) EP0TxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(TxFifoEP0REn), |
.fifoEmpty(TxFifoEP0Empty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP0TxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP0TxFifo), |
.fifoDataOut(TxFifoEP0Data) ); |
|
TxFifo #(EP1_FIFO_DEPTH, EP1_FIFO_ADDR_WIDTH) EP1TxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(TxFifoEP1REn), |
.fifoEmpty(TxFifoEP1Empty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP1TxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP1TxFifo), |
.fifoDataOut(TxFifoEP1Data) ); |
|
TxFifo #(EP2_FIFO_DEPTH, EP2_FIFO_ADDR_WIDTH) EP2TxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(TxFifoEP2REn), |
.fifoEmpty(TxFifoEP2Empty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP2TxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP2TxFifo), |
.fifoDataOut(TxFifoEP2Data) ); |
|
TxFifo #(EP3_FIFO_DEPTH, EP3_FIFO_ADDR_WIDTH) EP3TxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(TxFifoEP3REn), |
.fifoEmpty(TxFifoEP3Empty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP3TxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP3TxFifo), |
.fifoDataOut(TxFifoEP3Data) ); |
|
RxFifo #(EP0_FIFO_DEPTH, EP0_FIFO_ADDR_WIDTH) EP0RxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(RxFifoEP0WEn), |
.fifoFull(RxFifoEP0Full), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP0RxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP0RxFifo), |
.fifoDataIn(slaveRxFifoData) ); |
|
RxFifo #(EP1_FIFO_DEPTH, EP1_FIFO_ADDR_WIDTH) EP1RxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(RxFifoEP1WEn), |
.fifoFull(RxFifoEP1Full), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP1RxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP1RxFifo), |
.fifoDataIn(slaveRxFifoData) ); |
|
RxFifo #(EP2_FIFO_DEPTH, EP2_FIFO_ADDR_WIDTH) EP2RxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(RxFifoEP2WEn), |
.fifoFull(RxFifoEP2Full), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP2RxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP2RxFifo), |
.fifoDataIn(slaveRxFifoData) ); |
|
RxFifo #(EP3_FIFO_DEPTH, EP3_FIFO_ADDR_WIDTH) EP3RxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(RxFifoEP3WEn), |
.fifoFull(RxFifoEP3Full), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP3RxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP3RxFifo), |
.fifoDataIn(slaveRxFifoData) ); |
|
endmodule |
|
|
|
|
|
|
|
/verilog/usbhostslave/usbSlaveControl.v
0,0 → 1,521
////////////////////////////////////////////////////////////////////// |
//// //// |
//// usbSlaveControl.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module usbSlaveControl( |
busClk, |
rstSyncToBusClk, |
usbClk, |
rstSyncToUsbClk, |
//getPacket |
RxByteStatus, RxData, RxDataValid, |
SIERxTimeOut, RxFifoData, SIERxTimeOutEn, |
//speedCtrlMux |
fullSpeedRate, fullSpeedPol, |
connectSlaveToHost, |
//SCTxPortArbiter |
SCTxPortEn, SCTxPortRdy, |
SCTxPortData, SCTxPortCtrl, |
//rxStatusMonitor |
vBusDetect, |
connectStateIn, |
resumeDetectedIn, |
//USBHostControlBI |
busAddress, |
busDataIn, |
busDataOut, |
busWriteEn, |
busStrobe_i, |
SOFRxedIntOut, |
resetEventIntOut, |
resumeIntOut, |
transDoneIntOut, |
vBusDetIntOut, |
NAKSentIntOut, |
slaveControlSelect, |
//fifoMux |
TxFifoEP0REn, |
TxFifoEP1REn, |
TxFifoEP2REn, |
TxFifoEP3REn, |
TxFifoEP0Data, |
TxFifoEP1Data, |
TxFifoEP2Data, |
TxFifoEP3Data, |
TxFifoEP0Empty, |
TxFifoEP1Empty, |
TxFifoEP2Empty, |
TxFifoEP3Empty, |
RxFifoEP0WEn, |
RxFifoEP1WEn, |
RxFifoEP2WEn, |
RxFifoEP3WEn, |
RxFifoEP0Full, |
RxFifoEP1Full, |
RxFifoEP2Full, |
RxFifoEP3Full |
); |
|
input busClk; |
input rstSyncToBusClk; |
input usbClk; |
input rstSyncToUsbClk; |
//getPacket |
input [7:0] RxByteStatus; |
input [7:0] RxData; |
input RxDataValid; |
input SIERxTimeOut; |
output SIERxTimeOutEn; |
output [7:0] RxFifoData; |
//speedCtrlMux |
output fullSpeedRate; |
output fullSpeedPol; |
output connectSlaveToHost; |
//HCTxPortArbiter |
output SCTxPortEn; |
input SCTxPortRdy; |
output [7:0] SCTxPortData; |
output [7:0] SCTxPortCtrl; |
//rxStatusMonitor |
input vBusDetect; |
input [1:0] connectStateIn; |
input resumeDetectedIn; |
//USBHostControlBI |
input [4:0] busAddress; |
input [7:0] busDataIn; |
output [7:0] busDataOut; |
input busWriteEn; |
input busStrobe_i; |
output SOFRxedIntOut; |
output resetEventIntOut; |
output resumeIntOut; |
output transDoneIntOut; |
output vBusDetIntOut; |
output NAKSentIntOut; |
input slaveControlSelect; |
//fifoMux |
output TxFifoEP0REn; |
output TxFifoEP1REn; |
output TxFifoEP2REn; |
output TxFifoEP3REn; |
input [7:0] TxFifoEP0Data; |
input [7:0] TxFifoEP1Data; |
input [7:0] TxFifoEP2Data; |
input [7:0] TxFifoEP3Data; |
input TxFifoEP0Empty; |
input TxFifoEP1Empty; |
input TxFifoEP2Empty; |
input TxFifoEP3Empty; |
output RxFifoEP0WEn; |
output RxFifoEP1WEn; |
output RxFifoEP2WEn; |
output RxFifoEP3WEn; |
input RxFifoEP0Full; |
input RxFifoEP1Full; |
input RxFifoEP2Full; |
input RxFifoEP3Full; |
|
wire busClk; |
wire rstSyncToBusClk; |
wire usbClk; |
wire rstSyncToUsbClk; |
wire [7:0] RxByteStatus; |
wire [7:0] RxData; |
wire RxDataValid; |
wire SIERxTimeOut; |
wire SIERxTimeOutEn; |
wire [7:0] RxFifoData; |
wire fullSpeedRate; |
wire fullSpeedPol; |
wire connectSlaveToHost; |
wire [7:0] SCTxPortData; |
wire [7:0] SCTxPortCtrl; |
wire [1:0] connectStateIn; |
wire resumeDetectedIn; |
wire [4:0] busAddress; |
wire [7:0] busDataIn; |
wire [7:0] busDataOut; |
wire busWriteEn; |
wire busStrobe_i; |
wire SOFRxedIntOut; |
wire resetEventIntOut; |
wire resumeIntOut; |
wire transDoneIntOut; |
wire vBusDetIntOut; |
wire NAKSentIntOut; |
wire slaveControlSelect; |
wire TxFifoEP0REn; |
wire TxFifoEP1REn; |
wire TxFifoEP2REn; |
wire TxFifoEP3REn; |
wire [7:0] TxFifoEP0Data; |
wire [7:0] TxFifoEP1Data; |
wire [7:0] TxFifoEP2Data; |
wire [7:0] TxFifoEP3Data; |
wire TxFifoEP0Empty; |
wire TxFifoEP1Empty; |
wire TxFifoEP2Empty; |
wire TxFifoEP3Empty; |
wire RxFifoEP0WEn; |
wire RxFifoEP1WEn; |
wire RxFifoEP2WEn; |
wire RxFifoEP3WEn; |
wire RxFifoEP0Full; |
wire RxFifoEP1Full; |
wire RxFifoEP2Full; |
wire RxFifoEP3Full; |
|
//internal wiring |
wire [7:0] directCntlCntl; |
wire [7:0] directCntlData; |
wire directCntlGnt; |
wire directCntlReq; |
wire directCntlWEn; |
wire [7:0] sendPacketCntl; |
wire [7:0] sendPacketData; |
wire sendPacketGnt; |
wire sendPacketReq; |
wire sendPacketWEn; |
wire SCTxPortArbRdyOut; |
wire transDone; |
wire [1:0] directLineState; |
wire directLineCtrlEn; |
wire [3:0] RxPID; |
wire [1:0] connectStateOut; |
wire resumeIntFromRxStatusMon; |
wire [1:0] endP0TransTypeReg; |
wire [1:0] endP1TransTypeReg; |
wire [1:0] endP2TransTypeReg; |
wire [1:0] endP3TransTypeReg; |
wire [1:0] endP0NAKTransTypeReg; |
wire [1:0] endP1NAKTransTypeReg; |
wire [1:0] endP2NAKTransTypeReg; |
wire [1:0] endP3NAKTransTypeReg; |
wire [4:0] endP0ControlReg; |
wire [4:0] endP1ControlReg; |
wire [4:0] endP2ControlReg; |
wire [4:0] endP3ControlReg; |
wire [7:0] endP0StatusReg; |
wire [7:0] endP1StatusReg; |
wire [7:0] endP2StatusReg; |
wire [7:0] endP3StatusReg; |
wire [6:0] USBTgtAddress; |
wire [10:0] frameNum; |
wire clrEP0Rdy; |
wire clrEP1Rdy; |
wire clrEP2Rdy; |
wire clrEP3Rdy; |
wire SCGlobalEn; |
wire ACKRxed; |
wire CRCError; |
wire RXOverflow; |
wire RXTimeOut; |
wire bitStuffError; |
wire dataSequence; |
wire stallSent; |
wire NAKSent; |
wire SOFRxed; |
wire [4:0] endPControlReg; |
wire [1:0] transTypeNAK; |
wire [1:0] transType; |
wire [3:0] currEndP; |
wire getPacketREn; |
wire getPacketRdy; |
wire [3:0] slaveControllerPIDOut; |
wire slaveControllerReadyIn; |
wire slaveControllerWEnOut; |
wire TxFifoRE; |
wire [7:0] TxFifoData; |
wire TxFifoEmpty; |
wire RxFifoWE; |
wire RxFifoFull; |
wire resetEventFromRxStatusMon; |
wire clrEPRdy; |
wire endPMuxErrorsWEn; |
wire endPointReadyFromSlaveCtrlrToGetPkt; |
|
USBSlaveControlBI u_USBSlaveControlBI |
(.address(busAddress), |
.dataIn(busDataIn), |
.dataOut(busDataOut), |
.writeEn(busWriteEn), |
.strobe_i(busStrobe_i), |
.busClk(busClk), |
.rstSyncToBusClk(rstSyncToBusClk), |
.usbClk(usbClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.SOFRxedIntOut(SOFRxedIntOut), |
.resetEventIntOut(resetEventIntOut), |
.resumeIntOut(resumeIntOut), |
.transDoneIntOut(transDoneIntOut), |
.vBusDetIntOut(vBusDetIntOut), |
.NAKSentIntOut(NAKSentIntOut), |
.endP0TransTypeReg(endP0TransTypeReg), |
.endP0NAKTransTypeReg(endP0NAKTransTypeReg), |
.endP1TransTypeReg(endP1TransTypeReg), |
.endP1NAKTransTypeReg(endP1NAKTransTypeReg), |
.endP2TransTypeReg(endP2TransTypeReg), |
.endP2NAKTransTypeReg(endP2NAKTransTypeReg), |
.endP3TransTypeReg(endP3TransTypeReg), |
.endP3NAKTransTypeReg(endP3NAKTransTypeReg), |
.endP0ControlReg(endP0ControlReg), |
.endP1ControlReg(endP1ControlReg), |
.endP2ControlReg(endP2ControlReg), |
.endP3ControlReg(endP3ControlReg), |
.EP0StatusReg(endP0StatusReg), |
.EP1StatusReg(endP1StatusReg), |
.EP2StatusReg(endP2StatusReg), |
.EP3StatusReg(endP3StatusReg), |
.SCAddrReg(USBTgtAddress), |
.frameNum(frameNum), |
.connectStateIn(connectStateOut), |
.vBusDetectIn(vBusDetect), |
.SOFRxedIn(SOFRxed), |
.resetEventIn(resetEventFromRxStatusMon), |
.resumeIntIn(resumeIntFromRxStatusMon), |
.transDoneIn(transDone), |
.NAKSentIn(NAKSent), |
.slaveControlSelect(slaveControlSelect), |
.clrEP0Ready(clrEP0Rdy), |
.clrEP1Ready(clrEP1Rdy), |
.clrEP2Ready(clrEP2Rdy), |
.clrEP3Ready(clrEP3Rdy), |
.TxLineState(directLineState), |
.LineDirectControlEn(directLineCtrlEn), |
.fullSpeedPol(fullSpeedPol), |
.fullSpeedRate(fullSpeedRate), |
.connectSlaveToHost(connectSlaveToHost), |
.SCGlobalEn(SCGlobalEn) |
); |
|
slavecontroller u_slavecontroller |
(.CRCError(CRCError), |
.NAKSent(NAKSent), |
.RxByte(RxData), |
.RxDataWEn(RxDataValid), |
.RxOverflow(RXOverflow), |
.RxStatus(RxByteStatus), |
.RxTimeOut(RXTimeOut), |
.SCGlobalEn(SCGlobalEn), |
.SOFRxed(SOFRxed), |
.USBEndPControlReg(endPControlReg), |
.USBEndPNakTransTypeReg(transTypeNAK), |
.USBEndPTransTypeReg(transType), |
.USBEndP(currEndP), |
.USBTgtAddress(USBTgtAddress), |
.bitStuffError(bitStuffError), |
.clk(usbClk), |
.clrEPRdy(clrEPRdy), |
.endPMuxErrorsWEn(endPMuxErrorsWEn), |
.frameNum(frameNum), |
.getPacketREn(getPacketREn), |
.getPacketRdy(getPacketRdy), |
.rst(rstSyncToUsbClk), |
.sendPacketPID(slaveControllerPIDOut), |
.sendPacketRdy(slaveControllerReadyIn), |
.sendPacketWEn(slaveControllerWEnOut), |
.stallSent(stallSent), |
.transDone(transDone), |
.endPointReadyToGetPkt(endPointReadyFromSlaveCtrlrToGetPkt) |
); |
|
|
endpMux u_endpMux ( |
.clk(usbClk), |
.rst(rstSyncToUsbClk), |
.currEndP(currEndP), |
.NAKSent(NAKSent), |
.stallSent(stallSent), |
.CRCError(CRCError), |
.bitStuffError(bitStuffError), |
.RxOverflow(RXOverflow), |
.RxTimeOut(RXTimeOut), |
.dataSequence(dataSequence), |
.ACKRxed(ACKRxed), |
.transType(transType), |
.transTypeNAK(transTypeNAK), |
.endPControlReg(endPControlReg), |
.clrEPRdy(clrEPRdy), |
.endPMuxErrorsWEn(endPMuxErrorsWEn), |
.endP0ControlReg(endP0ControlReg), |
.endP1ControlReg(endP1ControlReg), |
.endP2ControlReg(endP2ControlReg), |
.endP3ControlReg(endP3ControlReg), |
.endP0StatusReg(endP0StatusReg), |
.endP1StatusReg(endP1StatusReg), |
.endP2StatusReg(endP2StatusReg), |
.endP3StatusReg(endP3StatusReg), |
.endP0TransTypeReg(endP0TransTypeReg), |
.endP1TransTypeReg(endP1TransTypeReg), |
.endP2TransTypeReg(endP2TransTypeReg), |
.endP3TransTypeReg(endP3TransTypeReg), |
.endP0NAKTransTypeReg(endP0NAKTransTypeReg), |
.endP1NAKTransTypeReg(endP1NAKTransTypeReg), |
.endP2NAKTransTypeReg(endP2NAKTransTypeReg), |
.endP3NAKTransTypeReg(endP3NAKTransTypeReg), |
.clrEP0Rdy(clrEP0Rdy), |
.clrEP1Rdy(clrEP1Rdy), |
.clrEP2Rdy(clrEP2Rdy), |
.clrEP3Rdy(clrEP3Rdy) |
); |
|
slaveSendPacket u_slaveSendPacket |
(.PID(slaveControllerPIDOut), |
.SCTxPortCntl(sendPacketCntl), |
.SCTxPortData(sendPacketData), |
.SCTxPortGnt(sendPacketGnt), |
.SCTxPortRdy(SCTxPortArbRdyOut), |
.SCTxPortReq(sendPacketReq), |
.SCTxPortWEn(sendPacketWEn), |
.clk(usbClk), |
.fifoData(TxFifoData), |
.fifoEmpty(TxFifoEmpty), |
.fifoReadEn(TxFifoRE), |
.rst(rstSyncToUsbClk), |
.sendPacketRdy(slaveControllerReadyIn), |
.sendPacketWEn(slaveControllerWEnOut) ); |
|
slaveDirectControl u_slaveDirectControl |
(.SCTxPortCntl(directCntlCntl), |
.SCTxPortData(directCntlData), |
.SCTxPortGnt(directCntlGnt), |
.SCTxPortRdy(SCTxPortArbRdyOut), |
.SCTxPortReq(directCntlReq), |
.SCTxPortWEn(directCntlWEn), |
.clk(usbClk), |
.directControlEn(directLineCtrlEn), |
.directControlLineState(directLineState), |
.rst(rstSyncToUsbClk) ); |
|
SCTxPortArbiter u_SCTxPortArbiter |
(.SCTxPortCntl(SCTxPortCtrl), |
.SCTxPortData(SCTxPortData), |
.SCTxPortRdyIn(SCTxPortRdy), |
.SCTxPortRdyOut(SCTxPortArbRdyOut), |
.SCTxPortWEnable(SCTxPortEn), |
.clk(usbClk), |
.directCntlCntl(directCntlCntl), |
.directCntlData(directCntlData), |
.directCntlGnt(directCntlGnt), |
.directCntlReq(directCntlReq), |
.directCntlWEn(directCntlWEn), |
.rst(rstSyncToUsbClk), |
.sendPacketCntl(sendPacketCntl), |
.sendPacketData(sendPacketData), |
.sendPacketGnt(sendPacketGnt), |
.sendPacketReq(sendPacketReq), |
.sendPacketWEn(sendPacketWEn) ); |
|
|
slaveGetPacket u_slaveGetPacket |
(.ACKRxed(ACKRxed), |
.CRCError(CRCError), |
.RXDataIn(RxData), |
.RXDataValid(RxDataValid), |
.RXFifoData(RxFifoData), |
.RXFifoFull(RxFifoFull), |
.RXFifoWEn(RxFifoWE), |
.RXPacketRdy(getPacketRdy), |
.RXStreamStatusIn(RxByteStatus), |
.RxPID(RxPID), |
.SIERxTimeOut(SIERxTimeOut), |
.SIERxTimeOutEn(SIERxTimeOutEn), |
.clk(usbClk), |
.RXOverflow(RXOverflow), |
.RXTimeOut(RXTimeOut), |
.bitStuffError(bitStuffError), |
.dataSequence(dataSequence), |
.getPacketEn(getPacketREn), |
.rst(rstSyncToUsbClk), |
.endPointReady(endPointReadyFromSlaveCtrlrToGetPkt) |
); |
|
slaveRxStatusMonitor u_slaveRxStatusMonitor |
(.connectStateIn(connectStateIn), |
.connectStateOut(connectStateOut), |
.resumeDetectedIn(resumeDetectedIn), |
.resetEventOut(resetEventFromRxStatusMon), |
.resumeIntOut(resumeIntFromRxStatusMon), |
.clk(usbClk), |
.rst(rstSyncToUsbClk) ); |
|
fifoMux u_fifoMux ( |
.currEndP(currEndP), |
//TxFifo |
.TxFifoREn(TxFifoRE), |
.TxFifoEP0REn(TxFifoEP0REn), |
.TxFifoEP1REn(TxFifoEP1REn), |
.TxFifoEP2REn(TxFifoEP2REn), |
.TxFifoEP3REn(TxFifoEP3REn), |
.TxFifoData(TxFifoData), |
.TxFifoEP0Data(TxFifoEP0Data), |
.TxFifoEP1Data(TxFifoEP1Data), |
.TxFifoEP2Data(TxFifoEP2Data), |
.TxFifoEP3Data(TxFifoEP3Data), |
.TxFifoEmpty(TxFifoEmpty), |
.TxFifoEP0Empty(TxFifoEP0Empty), |
.TxFifoEP1Empty(TxFifoEP1Empty), |
.TxFifoEP2Empty(TxFifoEP2Empty), |
.TxFifoEP3Empty(TxFifoEP3Empty), |
//RxFifo |
.RxFifoWEn(RxFifoWE), |
.RxFifoEP0WEn(RxFifoEP0WEn), |
.RxFifoEP1WEn(RxFifoEP1WEn), |
.RxFifoEP2WEn(RxFifoEP2WEn), |
.RxFifoEP3WEn(RxFifoEP3WEn), |
.RxFifoFull(RxFifoFull), |
.RxFifoEP0Full(RxFifoEP0Full), |
.RxFifoEP1Full(RxFifoEP1Full), |
.RxFifoEP2Full(RxFifoEP2Full), |
.RxFifoEP3Full(RxFifoEP3Full) |
); |
|
endmodule |
|
|
|
|
|
|
|
/verilog/usbhostslave/processRxBit.v
0,0 → 1,403
|
// File : ../RTL/serialInterfaceEngine/processRxBit.v |
// Generated : 11/10/06 05:37:22 |
// From : ../RTL/serialInterfaceEngine/processRxBit.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// processrxbit |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
|
module processRxBit (JBit, KBit, RxBitsIn, RxCtrlOut, RxDataOut, RxWireActive, clk, processRxBitRdy, processRxBitsWEn, processRxByteRdy, processRxByteWEn, resumeDetected, rst); |
input [1:0] JBit; |
input [1:0] KBit; |
input [1:0] RxBitsIn; |
input RxWireActive; |
input clk; |
input processRxBitsWEn; |
input processRxByteRdy; |
input rst; |
output [7:0] RxCtrlOut; |
output [7:0] RxDataOut; |
output processRxBitRdy; |
output processRxByteWEn; |
output resumeDetected; |
|
wire [1:0] JBit; |
wire [1:0] KBit; |
wire [1:0] RxBitsIn; |
reg [7:0] RxCtrlOut, next_RxCtrlOut; |
reg [7:0] RxDataOut, next_RxDataOut; |
wire RxWireActive; |
wire clk; |
reg processRxBitRdy, next_processRxBitRdy; |
wire processRxBitsWEn; |
wire processRxByteRdy; |
reg processRxByteWEn, next_processRxByteWEn; |
reg resumeDetected, next_resumeDetected; |
wire rst; |
|
// diagram signals declarations |
reg [3:0]RXBitCount, next_RXBitCount; |
reg [1:0]RXBitStMachCurrState, next_RXBitStMachCurrState; |
reg [7:0]RXByte, next_RXByte; |
reg [3:0]RXSameBitCount, next_RXSameBitCount; |
reg [1:0]RxBits, next_RxBits; |
reg bitStuffError, next_bitStuffError; |
reg [1:0]oldRXBits, next_oldRXBits; |
reg [4:0]resumeWaitCnt, next_resumeWaitCnt; |
|
// BINARY ENCODED state machine: prRxBit |
// State codes definitions: |
`define START 4'b0000 |
`define IDLE_FIRST_BIT 4'b0001 |
`define WAIT_BITS 4'b0010 |
`define IDLE_CHK_KBIT 4'b0011 |
`define DATA_RX_LAST_BIT 4'b0100 |
`define DATA_RX_CHK_SE0 4'b0101 |
`define DATA_RX_DATA_DESTUFF 4'b0110 |
`define DATA_RX_BYTE_SEND2 4'b0111 |
`define DATA_RX_BYTE_WAIT_RDY 4'b1000 |
`define RES_RX_CHK 4'b1001 |
`define DATA_RX_ERROR_CHK_RES 4'b1010 |
`define RES_END_CHK1 4'b1011 |
`define IDLE_WAIT_PRB_RDY 4'b1100 |
`define DATA_RX_WAIT_PRB_RDY 4'b1101 |
`define DATA_RX_ERROR_WAIT_RDY 4'b1110 |
|
reg [3:0] CurrState_prRxBit; |
reg [3:0] NextState_prRxBit; |
|
|
//-------------------------------------------------------------------- |
// Machine: prRxBit |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (RxBitsIn or RxBits or oldRXBits or RXSameBitCount or RXBitCount or RXByte or JBit or KBit or resumeWaitCnt or processRxBitsWEn or RXBitStMachCurrState or RxWireActive or processRxByteRdy or bitStuffError or processRxByteWEn or RxCtrlOut or RxDataOut or resumeDetected or processRxBitRdy or CurrState_prRxBit) |
begin : prRxBit_NextState |
NextState_prRxBit <= CurrState_prRxBit; |
// Set default values for outputs and signals |
next_processRxByteWEn <= processRxByteWEn; |
next_RxCtrlOut <= RxCtrlOut; |
next_RxDataOut <= RxDataOut; |
next_resumeDetected <= resumeDetected; |
next_RXBitStMachCurrState <= RXBitStMachCurrState; |
next_RxBits <= RxBits; |
next_RXSameBitCount <= RXSameBitCount; |
next_RXBitCount <= RXBitCount; |
next_oldRXBits <= oldRXBits; |
next_RXByte <= RXByte; |
next_bitStuffError <= bitStuffError; |
next_resumeWaitCnt <= resumeWaitCnt; |
next_processRxBitRdy <= processRxBitRdy; |
case (CurrState_prRxBit) |
`START: |
begin |
next_processRxByteWEn <= 1'b0; |
next_RxCtrlOut <= 8'h00; |
next_RxDataOut <= 8'h00; |
next_resumeDetected <= 1'b0; |
next_RXBitStMachCurrState <= `IDLE_BIT_ST; |
next_RxBits <= 2'b00; |
next_RXSameBitCount <= 4'h0; |
next_RXBitCount <= 4'h0; |
next_oldRXBits <= 2'b00; |
next_RXByte <= 8'h00; |
next_bitStuffError <= 1'b0; |
next_resumeWaitCnt <= 5'h0; |
next_processRxBitRdy <= 1'b1; |
NextState_prRxBit <= `WAIT_BITS; |
end |
`WAIT_BITS: |
if ((processRxBitsWEn == 1'b1) && (RXBitStMachCurrState == `WAIT_RESUME_ST)) |
begin |
NextState_prRxBit <= `RES_RX_CHK; |
next_RxBits <= RxBitsIn; |
next_processRxBitRdy <= 1'b0; |
end |
else if ((processRxBitsWEn == 1'b1) && (RXBitStMachCurrState == `DATA_RECEIVE_BIT_ST)) |
begin |
NextState_prRxBit <= `DATA_RX_CHK_SE0; |
next_RxBits <= RxBitsIn; |
next_processRxBitRdy <= 1'b0; |
end |
else if ((processRxBitsWEn == 1'b1) && (RXBitStMachCurrState == `IDLE_BIT_ST)) |
begin |
NextState_prRxBit <= `IDLE_CHK_KBIT; |
next_RxBits <= RxBitsIn; |
next_processRxBitRdy <= 1'b0; |
end |
else if ((processRxBitsWEn == 1'b1) && (RXBitStMachCurrState == `RESUME_END_WAIT_ST)) |
begin |
NextState_prRxBit <= `RES_END_CHK1; |
next_RxBits <= RxBitsIn; |
next_processRxBitRdy <= 1'b0; |
end |
`IDLE_FIRST_BIT: |
begin |
next_processRxByteWEn <= 1'b0; |
next_RXBitStMachCurrState <= `DATA_RECEIVE_BIT_ST; |
next_RXSameBitCount <= 4'h0; |
next_RXBitCount <= 4'h1; |
next_oldRXBits <= RxBits; |
//zero is always the first RZ data bit of a new packet |
next_RXByte <= 8'h00; |
NextState_prRxBit <= `WAIT_BITS; |
next_processRxBitRdy <= 1'b1; |
end |
`IDLE_CHK_KBIT: |
if ((RxBits == KBit) && (RxWireActive == 1'b1)) |
NextState_prRxBit <= `IDLE_WAIT_PRB_RDY; |
else |
begin |
NextState_prRxBit <= `WAIT_BITS; |
next_processRxBitRdy <= 1'b1; |
end |
`IDLE_WAIT_PRB_RDY: |
if (processRxByteRdy == 1'b1) |
begin |
NextState_prRxBit <= `IDLE_FIRST_BIT; |
next_RxDataOut <= 8'h00; |
//redundant data |
next_RxCtrlOut <= `DATA_START; |
//start of packet |
next_processRxByteWEn <= 1'b1; |
end |
`DATA_RX_LAST_BIT: |
begin |
next_processRxByteWEn <= 1'b0; |
next_RXBitStMachCurrState <= `IDLE_BIT_ST; |
NextState_prRxBit <= `WAIT_BITS; |
next_processRxBitRdy <= 1'b1; |
end |
`DATA_RX_CHK_SE0: |
begin |
next_bitStuffError <= 1'b0; |
if (RxBits == `SE0) |
NextState_prRxBit <= `DATA_RX_WAIT_PRB_RDY; |
else |
begin |
NextState_prRxBit <= `DATA_RX_DATA_DESTUFF; |
if (RxBits == oldRXBits) //if the current 'RxBits' are the same as the old 'RxBits', then |
begin |
next_RXSameBitCount <= RXSameBitCount + 1'b1; |
//inc 'RXSameBitCount' |
if (RXSameBitCount == `MAX_CONSEC_SAME_BITS) //if 'RXSameBitCount' == 6 there has been a bit stuff error |
next_bitStuffError <= 1'b1; |
//flag 'bitStuffError' |
else //else no bit stuffing error |
begin |
next_RXBitCount <= RXBitCount + 1'b1; |
if (RXBitCount != `MAX_CONSEC_SAME_BITS_PLUS1) begin |
next_processRxBitRdy <= 1'b1; |
//early indication of ready |
end |
next_RXByte <= { 1'b1, RXByte[7:1]}; |
//RZ bit = 1 (ie no change in 'RxBits') |
end |
end |
else //else current 'RxBits' are different from old 'RxBits' |
begin |
if (RXSameBitCount != `MAX_CONSEC_SAME_BITS) //if this is not the RZ 0 bit after 6 consecutive RZ 1s, then |
begin |
next_RXBitCount <= RXBitCount + 1'b1; |
if (RXBitCount != 4'h7) begin |
next_processRxBitRdy <= 1'b1; |
//early indication of ready |
end |
next_RXByte <= {1'b0, RXByte[7:1]}; |
//RZ bit = 0 (ie current'RxBits' is different than old 'RxBits') |
end |
next_RXSameBitCount <= 4'h0; |
//reset 'RXSameBitCount' |
end |
next_oldRXBits <= RxBits; |
end |
end |
`DATA_RX_WAIT_PRB_RDY: |
if (processRxByteRdy == 1'b1) |
begin |
NextState_prRxBit <= `DATA_RX_LAST_BIT; |
next_RxDataOut <= 8'h00; |
//redundant data |
next_RxCtrlOut <= `DATA_STOP; |
//end of packet |
next_processRxByteWEn <= 1'b1; |
end |
`DATA_RX_DATA_DESTUFF: |
if (RXBitCount == 4'h8 & bitStuffError == 1'b0) |
NextState_prRxBit <= `DATA_RX_BYTE_WAIT_RDY; |
else if (bitStuffError == 1'b1) |
NextState_prRxBit <= `DATA_RX_ERROR_WAIT_RDY; |
else |
begin |
NextState_prRxBit <= `WAIT_BITS; |
next_processRxBitRdy <= 1'b1; |
end |
`DATA_RX_BYTE_SEND2: |
begin |
next_processRxByteWEn <= 1'b0; |
NextState_prRxBit <= `WAIT_BITS; |
next_processRxBitRdy <= 1'b1; |
end |
`DATA_RX_BYTE_WAIT_RDY: |
if (processRxByteRdy == 1'b1) |
begin |
NextState_prRxBit <= `DATA_RX_BYTE_SEND2; |
next_RXBitCount <= 4'h0; |
next_RxDataOut <= RXByte; |
next_RxCtrlOut <= `DATA_STREAM; |
next_processRxByteWEn <= 1'b1; |
end |
`DATA_RX_ERROR_CHK_RES: |
begin |
next_processRxByteWEn <= 1'b0; |
if (RxBits == JBit) //if current bit is a JBit, then |
next_RXBitStMachCurrState <= `IDLE_BIT_ST; |
//next state is idle |
else //else |
begin |
next_RXBitStMachCurrState <= `WAIT_RESUME_ST; |
//check for resume |
next_resumeWaitCnt <= 5'h0; |
end |
NextState_prRxBit <= `WAIT_BITS; |
next_processRxBitRdy <= 1'b1; |
end |
`DATA_RX_ERROR_WAIT_RDY: |
if (processRxByteRdy == 1'b1) |
begin |
NextState_prRxBit <= `DATA_RX_ERROR_CHK_RES; |
next_RxDataOut <= 8'h00; |
//redundant data |
next_RxCtrlOut <= `DATA_BIT_STUFF_ERROR; |
next_processRxByteWEn <= 1'b1; |
end |
`RES_RX_CHK: |
begin |
if (RxBits != KBit) //can only be a resume if line remains in Kbit state |
next_RXBitStMachCurrState <= `IDLE_BIT_ST; |
else |
begin |
next_resumeWaitCnt <= resumeWaitCnt + 1'b1; |
//if we've waited long enough, then |
if (resumeWaitCnt == `RESUME_RX_WAIT_TIME) |
begin |
next_RXBitStMachCurrState <= `RESUME_END_WAIT_ST; |
next_resumeDetected <= 1'b1; |
//report resume detected |
end |
end |
NextState_prRxBit <= `WAIT_BITS; |
next_processRxBitRdy <= 1'b1; |
end |
`RES_END_CHK1: |
begin |
if (RxBits != KBit) //line must leave KBit state for the end of resume |
begin |
next_RXBitStMachCurrState <= `IDLE_BIT_ST; |
next_resumeDetected <= 1'b0; |
//clear resume detected flag |
end |
NextState_prRxBit <= `WAIT_BITS; |
next_processRxBitRdy <= 1'b1; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : prRxBit_CurrentState |
if (rst) |
CurrState_prRxBit <= `START; |
else |
CurrState_prRxBit <= NextState_prRxBit; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : prRxBit_RegOutput |
if (rst) |
begin |
RXBitStMachCurrState <= `IDLE_BIT_ST; |
RxBits <= 2'b00; |
RXSameBitCount <= 4'h0; |
RXBitCount <= 4'h0; |
oldRXBits <= 2'b00; |
RXByte <= 8'h00; |
bitStuffError <= 1'b0; |
resumeWaitCnt <= 5'h0; |
processRxByteWEn <= 1'b0; |
RxCtrlOut <= 8'h00; |
RxDataOut <= 8'h00; |
resumeDetected <= 1'b0; |
processRxBitRdy <= 1'b1; |
end |
else |
begin |
RXBitStMachCurrState <= next_RXBitStMachCurrState; |
RxBits <= next_RxBits; |
RXSameBitCount <= next_RXSameBitCount; |
RXBitCount <= next_RXBitCount; |
oldRXBits <= next_oldRXBits; |
RXByte <= next_RXByte; |
bitStuffError <= next_bitStuffError; |
resumeWaitCnt <= next_resumeWaitCnt; |
processRxByteWEn <= next_processRxByteWEn; |
RxCtrlOut <= next_RxCtrlOut; |
RxDataOut <= next_RxDataOut; |
resumeDetected <= next_resumeDetected; |
processRxBitRdy <= next_processRxBitRdy; |
end |
end |
|
endmodule |
/verilog/usbhostslave/sendPacketArbiter.v
0,0 → 1,182
|
// File : ../RTL/hostController/sendpacketarbiter.v |
// Generated : 11/10/06 05:37:20 |
// From : ../RTL/hostController/sendpacketarbiter.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// sendpacketarbiter |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_constants_h.v" |
|
module sendPacketArbiter (HCTxGnt, HCTxReq, HC_PID, HC_SP_WEn, SOFTxGnt, SOFTxReq, SOF_SP_WEn, clk, rst, sendPacketPID, sendPacketWEnable); |
input HCTxReq; |
input [3:0] HC_PID; |
input HC_SP_WEn; |
input SOFTxReq; |
input SOF_SP_WEn; |
input clk; |
input rst; |
output HCTxGnt; |
output SOFTxGnt; |
output [3:0] sendPacketPID; |
output sendPacketWEnable; |
|
reg HCTxGnt, next_HCTxGnt; |
wire HCTxReq; |
wire [3:0] HC_PID; |
wire HC_SP_WEn; |
reg SOFTxGnt, next_SOFTxGnt; |
wire SOFTxReq; |
wire SOF_SP_WEn; |
wire clk; |
wire rst; |
reg [3:0] sendPacketPID, next_sendPacketPID; |
reg sendPacketWEnable, next_sendPacketWEnable; |
|
// diagram signals declarations |
reg muxSOFNotHC, next_muxSOFNotHC; |
|
// BINARY ENCODED state machine: sendPktArb |
// State codes definitions: |
`define HC_ACT 2'b00 |
`define SOF_ACT 2'b01 |
`define SARB_WAIT_REQ 2'b10 |
`define START_SARB 2'b11 |
|
reg [1:0] CurrState_sendPktArb; |
reg [1:0] NextState_sendPktArb; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
// hostController/SOFTransmit mux |
always @(muxSOFNotHC or SOF_SP_WEn or HC_SP_WEn or HC_PID) |
begin |
if (muxSOFNotHC == 1'b1) |
begin |
sendPacketWEnable <= SOF_SP_WEn; |
sendPacketPID <= `SOF; |
end |
else |
begin |
sendPacketWEnable <= HC_SP_WEn; |
sendPacketPID <= HC_PID; |
end |
end |
|
//-------------------------------------------------------------------- |
// Machine: sendPktArb |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (HCTxReq or SOFTxReq or HCTxGnt or SOFTxGnt or muxSOFNotHC or CurrState_sendPktArb) |
begin : sendPktArb_NextState |
NextState_sendPktArb <= CurrState_sendPktArb; |
// Set default values for outputs and signals |
next_HCTxGnt <= HCTxGnt; |
next_SOFTxGnt <= SOFTxGnt; |
next_muxSOFNotHC <= muxSOFNotHC; |
case (CurrState_sendPktArb) |
`HC_ACT: |
if (HCTxReq == 1'b0) |
begin |
NextState_sendPktArb <= `SARB_WAIT_REQ; |
next_HCTxGnt <= 1'b0; |
end |
`SOF_ACT: |
if (SOFTxReq == 1'b0) |
begin |
NextState_sendPktArb <= `SARB_WAIT_REQ; |
next_SOFTxGnt <= 1'b0; |
end |
`SARB_WAIT_REQ: |
if (SOFTxReq == 1'b1) |
begin |
NextState_sendPktArb <= `SOF_ACT; |
next_SOFTxGnt <= 1'b1; |
next_muxSOFNotHC <= 1'b1; |
end |
else if (HCTxReq == 1'b1) |
begin |
NextState_sendPktArb <= `HC_ACT; |
next_HCTxGnt <= 1'b1; |
next_muxSOFNotHC <= 1'b0; |
end |
`START_SARB: |
NextState_sendPktArb <= `SARB_WAIT_REQ; |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : sendPktArb_CurrentState |
if (rst) |
CurrState_sendPktArb <= `START_SARB; |
else |
CurrState_sendPktArb <= NextState_sendPktArb; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : sendPktArb_RegOutput |
if (rst) |
begin |
muxSOFNotHC <= 1'b0; |
SOFTxGnt <= 1'b0; |
HCTxGnt <= 1'b0; |
end |
else |
begin |
muxSOFNotHC <= next_muxSOFNotHC; |
SOFTxGnt <= next_SOFTxGnt; |
HCTxGnt <= next_HCTxGnt; |
end |
end |
|
endmodule |
/verilog/usbhostslave/SOFController.v
0,0 → 1,181
|
// File : ../RTL/hostController/sofcontroller.v |
// Generated : 11/10/06 05:37:21 |
// From : ../RTL/hostController/sofcontroller.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// sofcontroller |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
module SOFController (HCTxPortCntl, HCTxPortData, HCTxPortGnt, HCTxPortRdy, HCTxPortReq, HCTxPortWEn, SOFEnable, SOFTimerClr, SOFTimer, clk, rst); |
input HCTxPortGnt; |
input HCTxPortRdy; |
input SOFEnable; |
input SOFTimerClr; |
input clk; |
input rst; |
output [7:0] HCTxPortCntl; |
output [7:0] HCTxPortData; |
output HCTxPortReq; |
output HCTxPortWEn; |
output [15:0] SOFTimer; |
|
reg [7:0] HCTxPortCntl, next_HCTxPortCntl; |
reg [7:0] HCTxPortData, next_HCTxPortData; |
wire HCTxPortGnt; |
wire HCTxPortRdy; |
reg HCTxPortReq, next_HCTxPortReq; |
reg HCTxPortWEn, next_HCTxPortWEn; |
wire SOFEnable; |
wire SOFTimerClr; |
reg [15:0] SOFTimer, next_SOFTimer; |
wire clk; |
wire rst; |
|
// BINARY ENCODED state machine: sofCntl |
// State codes definitions: |
`define START_SC 3'b000 |
`define WAIT_SOF_EN 3'b001 |
`define WAIT_SEND_RESUME 3'b010 |
`define INC_TIMER 3'b011 |
`define SC_WAIT_GNT 3'b100 |
`define CLR_WEN 3'b101 |
|
reg [2:0] CurrState_sofCntl; |
reg [2:0] NextState_sofCntl; |
|
|
//-------------------------------------------------------------------- |
// Machine: sofCntl |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (SOFTimerClr or SOFTimer or SOFEnable or HCTxPortRdy or HCTxPortGnt or HCTxPortReq or HCTxPortWEn or HCTxPortData or HCTxPortCntl or CurrState_sofCntl) |
begin : sofCntl_NextState |
NextState_sofCntl <= CurrState_sofCntl; |
// Set default values for outputs and signals |
next_HCTxPortReq <= HCTxPortReq; |
next_HCTxPortWEn <= HCTxPortWEn; |
next_HCTxPortData <= HCTxPortData; |
next_HCTxPortCntl <= HCTxPortCntl; |
next_SOFTimer <= SOFTimer; |
case (CurrState_sofCntl) |
`START_SC: |
NextState_sofCntl <= `WAIT_SOF_EN; |
`WAIT_SOF_EN: |
if (SOFEnable == 1'b1) |
begin |
NextState_sofCntl <= `SC_WAIT_GNT; |
next_HCTxPortReq <= 1'b1; |
end |
`WAIT_SEND_RESUME: |
if (HCTxPortRdy == 1'b1) |
begin |
NextState_sofCntl <= `CLR_WEN; |
next_HCTxPortWEn <= 1'b1; |
next_HCTxPortData <= 8'h00; |
next_HCTxPortCntl <= `TX_RESUME_START; |
end |
`INC_TIMER: |
begin |
next_HCTxPortReq <= 1'b0; |
if (SOFTimerClr == 1'b1) |
next_SOFTimer <= 16'h0000; |
else |
next_SOFTimer <= SOFTimer + 1'b1; |
if (SOFEnable == 1'b0) |
begin |
NextState_sofCntl <= `WAIT_SOF_EN; |
next_SOFTimer <= 16'h0000; |
end |
end |
`SC_WAIT_GNT: |
if (HCTxPortGnt == 1'b1) |
NextState_sofCntl <= `WAIT_SEND_RESUME; |
`CLR_WEN: |
begin |
next_HCTxPortWEn <= 1'b0; |
NextState_sofCntl <= `INC_TIMER; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : sofCntl_CurrentState |
if (rst) |
CurrState_sofCntl <= `START_SC; |
else |
CurrState_sofCntl <= NextState_sofCntl; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : sofCntl_RegOutput |
if (rst) |
begin |
SOFTimer <= 16'h0000; |
HCTxPortCntl <= 8'h00; |
HCTxPortData <= 8'h00; |
HCTxPortWEn <= 1'b0; |
HCTxPortReq <= 1'b0; |
end |
else |
begin |
SOFTimer <= next_SOFTimer; |
HCTxPortCntl <= next_HCTxPortCntl; |
HCTxPortData <= next_HCTxPortData; |
HCTxPortWEn <= next_HCTxPortWEn; |
HCTxPortReq <= next_HCTxPortReq; |
end |
end |
|
endmodule |
/verilog/usbhostslave/updateCRC5.v
0,0 → 1,112
////////////////////////////////////////////////////////////////////// |
//// //// |
//// updateCRC5.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module updateCRC5 (rstCRC, CRCResult, CRCEn, CRC5_8BitIn, dataIn, ready, clk, rst); |
input rstCRC; |
input CRCEn; |
input CRC5_8BitIn; |
input [7:0] dataIn; |
input clk; |
input rst; |
output [4:0] CRCResult; |
output ready; |
|
wire rstCRC; |
wire CRCEn; |
wire CRC5_8BitIn; |
wire [7:0] dataIn; |
wire clk; |
wire rst; |
reg [4:0] CRCResult; |
reg ready; |
|
reg doUpdateCRC; |
reg [7:0] data; |
reg [3:0] loopEnd; |
reg [3:0] i; |
|
always @(posedge clk) |
begin |
if (rst == 1'b1 || rstCRC == 1'b1) begin |
doUpdateCRC <= 1'b0; |
i <= 4'h0; |
CRCResult <= 5'h1f; |
ready <= 1'b1; |
end |
else |
begin |
if (doUpdateCRC == 1'b0) begin |
if (CRCEn == 1'b1) begin |
ready <= 1'b0; |
doUpdateCRC <= 1'b1; |
data <= dataIn; |
if (CRC5_8BitIn == 1'b1) begin |
loopEnd <= 4'h7; |
end |
else begin |
loopEnd <= 4'h2; |
end |
end |
end |
else begin |
i <= i + 1'b1; |
if ( (CRCResult[0] ^ data[0]) == 1'b1) begin |
CRCResult <= {1'b0, CRCResult[4:1]} ^ 5'h14; |
end |
else begin |
CRCResult <= {1'b0, CRCResult[4:1]}; |
end |
data <= {1'b0, data[7:1]}; |
if (i == loopEnd) begin |
doUpdateCRC <= 1'b0; |
i <= 4'h0; |
ready <= 1'b1; |
end |
end |
end |
end |
|
|
endmodule |
/verilog/usbhostslave/usbSerialInterfaceEngine.v
0,0 → 1,394
////////////////////////////////////////////////////////////////////// |
//// //// |
//// usbSerialInterfaceEngine.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module usbSerialInterfaceEngine( |
clk, rst, |
//readUSBWireData |
USBWireDataIn, |
USBWireDataInTick, |
//writeUSBWireData |
USBWireDataOut, |
USBWireCtrlOut, |
USBWireDataOutTick, |
//SIEReceiver |
connectState, |
//processRxBit |
resumeDetected, |
//processRxByte |
RxCtrlOut, |
RxDataOutWEn, |
RxDataOut, |
//SIETransmitter |
SIEPortCtrlIn, |
SIEPortDataIn, |
SIEPortTxRdy, |
SIEPortWEn, |
//lineControlUpdate |
fullSpeedPolarity, |
fullSpeedBitRate, |
noActivityTimeOut, |
noActivityTimeOutEnable |
); |
|
input clk, rst; |
//readUSBWireData |
input [1:0] USBWireDataIn; |
output USBWireDataInTick; |
output noActivityTimeOut; |
input noActivityTimeOutEnable; |
|
//writeUSBWireData |
output [1:0] USBWireDataOut; |
output USBWireCtrlOut; |
output USBWireDataOutTick; |
|
//SIEReceiver |
output [1:0] connectState; |
//processRxBit |
output resumeDetected; |
//processRxByte |
output [7:0] RxCtrlOut; |
output RxDataOutWEn; |
output [7:0] RxDataOut; |
//SIETransmitter |
input [7:0] SIEPortCtrlIn; |
input [7:0] SIEPortDataIn; |
output SIEPortTxRdy; |
input SIEPortWEn; |
//lineControlUpdate |
input fullSpeedPolarity; |
input fullSpeedBitRate; |
|
wire clk, rst; |
//readUSBWireData |
wire [1:0] USBWireDataIn; |
wire USBWireDataInTick; |
//writeUSBWireData |
wire [1:0] USBWireDataOut; |
wire USBWireCtrlOut; |
wire noActivityTimeOut; |
wire USBWireDataOutTick; |
//SIEReceiver |
wire [1:0] connectState; |
//processRxBit |
wire resumeDetected; |
//processRxByte |
wire [7:0] RxCtrlOut; |
wire RxDataOutWEn; |
wire [7:0] RxDataOut; |
//SIETransmitter |
wire [7:0] SIEPortCtrlIn; |
wire [7:0] SIEPortDataIn; |
wire SIEPortTxRdy; |
wire SIEPortWEn; |
//lineControlUpdate |
wire fullSpeedPolarity; |
wire fullSpeedBitRate; |
|
//internal wiring |
wire processRxBitsWEn; |
wire processRxBitRdy; |
wire [1:0] RxWireDataFromWireRx; |
wire RxWireDataWEn; |
wire TxWireActiveDrive; |
wire [1:0] TxBitsFromArbToWire; |
wire TxCtrlFromArbToWire; |
wire USBWireRdy; |
wire USBWireWEn; |
wire USBWireReadyFromTxArb; |
wire prcTxByteCtrl; |
wire [1:0] prcTxByteData; |
wire prcTxByteGnt; |
wire prcTxByteReq; |
wire prcTxByteWEn; |
wire SIETxCtrl; |
wire [1:0] SIETxData; |
wire SIETxGnt; |
wire SIETxReq; |
wire SIETxWEn; |
wire [7:0] TxByteFromSIEToPrcTxByte; |
wire [7:0] TxCtrlFromSIEToPrcTxByte; |
wire [1:0] JBit; |
wire [1:0] KBit; |
wire processRxByteWEn; |
wire [7:0] RxDataFromPrcRxBitToPrcRxByte; |
wire [7:0] RxCtrlFromPrcRxBitToPrcRxByte; |
wire processRxByteRdy; |
//Rx CRC |
wire RxCRC16En; |
wire [15:0] RxCRC16Result; |
wire RxCRC16UpdateRdy; |
wire RxCRC5En; |
wire [4:0] RxCRC5Result; |
wire RxCRC5_8Bit; |
wire [7:0] RxCRCData; |
wire RxRstCRC; |
wire RxCRC5UpdateRdy; |
//Tx CRC |
wire TxCRC16En; |
wire [15:0] TxCRC16Result; |
wire TxCRC16UpdateRdy; |
wire TxCRC5En; |
wire [4:0] TxCRC5Result; |
wire TxCRC5_8Bit; |
wire [7:0] TxCRCData; |
wire TxRstCRC; |
wire TxCRC5UpdateRdy; |
|
wire processTxByteRdy; |
wire processTxByteWEn; |
|
wire SIEFsRate; |
wire TxFSRateFromSIETxToPrcTxByte; |
wire prcTxByteFSRate; |
wire FSRateFromArbiterToWire; |
|
wire RxWireActive; |
|
lineControlUpdate u_lineControlUpdate |
(.fullSpeedPolarity(fullSpeedPolarity), |
.fullSpeedBitRate(fullSpeedBitRate), |
.JBit(JBit), |
.KBit(KBit) ); |
|
SIEReceiver u_SIEReceiver |
( |
.RxWireDataIn(RxWireDataFromWireRx), |
.RxWireDataWEn(RxWireDataWEn), |
.clk(clk), |
.connectState(connectState), |
.rst(rst) ); |
|
|
processRxBit u_processRxBit |
(.JBit(JBit), |
.KBit(KBit), |
.RxBitsIn(RxWireDataFromWireRx), |
.RxCtrlOut(RxCtrlFromPrcRxBitToPrcRxByte), |
.RxDataOut(RxDataFromPrcRxBitToPrcRxByte), |
.clk(clk), |
.processRxBitRdy(processRxBitRdy), |
.processRxBitsWEn(RxWireDataWEn), |
.processRxByteWEn(processRxByteWEn), |
.resumeDetected(resumeDetected), |
.rst(rst), |
.processRxByteRdy(processRxByteRdy), |
.RxWireActive(RxWireActive) |
); |
|
processRxByte u_processRxByte |
(.CRC16En(RxCRC16En), |
.CRC16Result(RxCRC16Result), |
.CRC16UpdateRdy(RxCRC16UpdateRdy), |
.CRC5En(RxCRC5En), |
.CRC5Result(RxCRC5Result), |
.CRC5_8Bit(RxCRC5_8Bit), |
.CRC5UpdateRdy(RxCRC5UpdateRdy), |
.CRCData(RxCRCData), |
.RxByteIn(RxDataFromPrcRxBitToPrcRxByte), |
.RxCtrlIn(RxCtrlFromPrcRxBitToPrcRxByte), |
.RxCtrlOut(RxCtrlOut), |
.RxDataOutWEn(RxDataOutWEn), |
.RxDataOut(RxDataOut), |
.clk(clk), |
.processRxDataInWEn(processRxByteWEn), |
.rst(rst), |
.rstCRC(RxRstCRC), |
.processRxByteRdy(processRxByteRdy) ); |
|
|
updateCRC5 RxUpdateCRC5 |
(.rstCRC(RxRstCRC), |
.CRCResult(RxCRC5Result), |
.CRCEn(RxCRC5En), |
.CRC5_8BitIn(RxCRC5_8Bit), |
.dataIn(RxCRCData), |
.ready(RxCRC5UpdateRdy), |
.clk(clk), |
.rst(rst) ); |
|
updateCRC16 RxUpdateCRC16 |
(.rstCRC(RxRstCRC), |
.CRCResult(RxCRC16Result), |
.CRCEn(RxCRC16En), |
.dataIn(RxCRCData), |
.ready(RxCRC16UpdateRdy), |
.clk(clk), |
.rst(rst) ); |
|
SIETransmitter u_SIETransmitter |
(.CRC16En(TxCRC16En), |
.CRC16Result(TxCRC16Result), |
.CRC5En(TxCRC5En), |
.CRC5Result(TxCRC5Result), |
.CRC5_8Bit(TxCRC5_8Bit), |
.CRCData(TxCRCData), |
.CRC5UpdateRdy(TxCRC5UpdateRdy), |
.CRC16UpdateRdy(TxCRC16UpdateRdy), |
.JBit(JBit), |
.KBit(KBit), |
.SIEPortCtrlIn(SIEPortCtrlIn), |
.SIEPortDataIn(SIEPortDataIn), |
.SIEPortTxRdy(SIEPortTxRdy), |
.SIEPortWEn(SIEPortWEn), |
.TxByteOutCtrl(TxCtrlFromSIEToPrcTxByte), |
.TxByteOut(TxByteFromSIEToPrcTxByte), |
.USBWireCtrl(SIETxCtrl), |
.USBWireData(SIETxData), |
.USBWireGnt(SIETxGnt), |
.USBWireRdy(USBWireReadyFromTxArb), |
.USBWireReq(SIETxReq), |
.USBWireWEn(SIETxWEn), |
.clk(clk), |
.processTxByteRdy(processTxByteRdy), |
.processTxByteWEn(processTxByteWEn), |
.rst(rst), |
.rstCRC(TxRstCRC), |
.USBWireFullSpeedRate(SIEFsRate), |
.TxByteOutFullSpeedRate(TxFSRateFromSIETxToPrcTxByte), |
.fullSpeedRateIn(fullSpeedBitRate) |
); |
|
updateCRC5 TxUpdateCRC5 |
(.rstCRC(TxRstCRC), |
.CRCResult(TxCRC5Result), |
.CRCEn(TxCRC5En), |
.CRC5_8BitIn(TxCRC5_8Bit), |
.dataIn(TxCRCData), |
.ready(TxCRC5UpdateRdy), |
.clk(clk), |
.rst(rst) ); |
|
updateCRC16 TxUpdateCRC16 |
(.rstCRC(TxRstCRC), |
.CRCResult(TxCRC16Result), |
.CRCEn(TxCRC16En), |
.dataIn(TxCRCData), |
.ready(TxCRC16UpdateRdy), |
.clk(clk), |
.rst(rst) ); |
|
processTxByte u_processTxByte |
(.JBit(JBit), |
.KBit(KBit), |
.TxByteCtrlIn(TxCtrlFromSIEToPrcTxByte), |
.TxByteIn(TxByteFromSIEToPrcTxByte), |
.USBWireCtrl(prcTxByteCtrl), |
.USBWireData(prcTxByteData), |
.USBWireGnt(prcTxByteGnt), |
.USBWireRdy(USBWireReadyFromTxArb), |
.USBWireReq(prcTxByteReq), |
.USBWireWEn(prcTxByteWEn), |
.clk(clk), |
.processTxByteRdy(processTxByteRdy), |
.processTxByteWEn(processTxByteWEn), |
.rst(rst), |
.USBWireFullSpeedRate(prcTxByteFSRate), |
.TxByteFullSpeedRateIn(TxFSRateFromSIETxToPrcTxByte) |
); |
|
USBTxWireArbiter u_USBTxWireArbiter |
(.SIETxCtrl(SIETxCtrl), |
.SIETxData(SIETxData), |
.SIETxGnt(SIETxGnt), |
.SIETxReq(SIETxReq), |
.SIETxWEn(SIETxWEn), |
.TxBits(TxBitsFromArbToWire), |
.TxCtl(TxCtrlFromArbToWire), |
.USBWireRdyIn(USBWireRdy), |
.USBWireRdyOut(USBWireReadyFromTxArb), |
.USBWireWEn(USBWireWEn), |
.clk(clk), |
.prcTxByteCtrl(prcTxByteCtrl), |
.prcTxByteData(prcTxByteData), |
.prcTxByteGnt(prcTxByteGnt), |
.prcTxByteReq(prcTxByteReq), |
.prcTxByteWEn(prcTxByteWEn), |
.rst(rst), |
.SIETxFSRate(SIEFsRate), |
.prcTxByteFSRate(prcTxByteFSRate), |
.TxFSRate(FSRateFromArbiterToWire) |
); |
|
writeUSBWireData u_writeUSBWireData |
(.TxBitsIn(TxBitsFromArbToWire), |
.TxBitsOut(USBWireDataOut), |
.TxDataOutTick(USBWireDataOutTick), |
.TxCtrlIn(TxCtrlFromArbToWire), |
.TxCtrlOut(USBWireCtrlOut), |
.USBWireRdy(USBWireRdy), |
.USBWireWEn(USBWireWEn), |
.TxWireActiveDrive(TxWireActiveDrive), |
.fullSpeedRate(FSRateFromArbiterToWire), |
.clk(clk), |
.rst(rst) |
); |
|
|
|
readUSBWireData u_readUSBWireData |
(.RxBitsIn(USBWireDataIn), |
.RxDataInTick(USBWireDataInTick), |
.RxBitsOut(RxWireDataFromWireRx), |
.SIERxRdyIn(processRxBitRdy), |
.SIERxWEn(RxWireDataWEn), |
.fullSpeedRate(fullSpeedBitRate), |
.TxWireActiveDrive(TxWireActiveDrive), |
.clk(clk), |
.rst(rst), |
.noActivityTimeOut(noActivityTimeOut), |
.RxWireActive(RxWireActive), |
.noActivityTimeOutEnable(noActivityTimeOutEnable) |
); |
|
|
endmodule |
|
|
|
|
|
|
|
/verilog/usbhostslave/slaveRxStatusMonitor.v
0,0 → 1,95
////////////////////////////////////////////////////////////////////// |
//// //// |
//// slaveRxStatusMonitor.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module slaveRxStatusMonitor(connectStateIn, connectStateOut, resumeDetectedIn, resetEventOut, resumeIntOut, clk, rst); |
|
input [1:0] connectStateIn; |
input resumeDetectedIn; |
input clk; |
input rst; |
output resetEventOut; |
output [1:0] connectStateOut; |
output resumeIntOut; |
|
wire [1:0] connectStateIn; |
wire resumeDetectedIn; |
reg resetEventOut; |
reg [1:0] connectStateOut; |
reg resumeIntOut; |
wire clk; |
wire rst; |
|
reg [1:0]oldConnectState; |
reg oldResumeDetected; |
|
always @(connectStateIn) |
begin |
connectStateOut <= connectStateIn; |
end |
|
|
always @(posedge clk) |
begin |
if (rst == 1'b1) |
begin |
oldConnectState <= connectStateIn; |
oldResumeDetected <= resumeDetectedIn; |
end |
else |
begin |
oldConnectState <= connectStateIn; |
oldResumeDetected <= resumeDetectedIn; |
if (oldConnectState != connectStateIn) |
resetEventOut <= 1'b1; |
else |
resetEventOut <= 1'b0; |
if (resumeDetectedIn == 1'b1 && oldResumeDetected == 1'b0) |
resumeIntOut <= 1'b1; |
else |
resumeIntOut <= 1'b0; |
end |
end |
|
endmodule |
/verilog/usbhostslave/USBHostControlBI.v
0,0 → 1,479
////////////////////////////////////////////////////////////////////// |
//// //// |
//// USBHostControlBI.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_hostcontrol_h.v" |
|
module USBHostControlBI (address, dataIn, dataOut, writeEn, |
strobe_i, |
busClk, |
rstSyncToBusClk, |
usbClk, |
rstSyncToUsbClk, |
SOFSentIntOut, connEventIntOut, resumeIntOut, transDoneIntOut, |
TxTransTypeReg, TxSOFEnableReg, |
TxAddrReg, TxEndPReg, frameNumIn, |
RxPktStatusIn, RxPIDIn, |
connectStateIn, |
SOFSentIn, connEventIn, resumeIntIn, transDoneIn, |
hostControlSelect, |
clrTransReq, |
preambleEn, |
SOFSync, |
TxLineState, |
LineDirectControlEn, |
fullSpeedPol, |
fullSpeedRate, |
transReq, |
isoEn, |
SOFTimer |
); |
input [3:0] address; |
input [7:0] dataIn; |
input writeEn; |
input strobe_i; |
input busClk; |
input rstSyncToBusClk; |
input usbClk; |
input rstSyncToUsbClk; |
output [7:0] dataOut; |
output SOFSentIntOut; |
output connEventIntOut; |
output resumeIntOut; |
output transDoneIntOut; |
|
output [1:0] TxTransTypeReg; |
output TxSOFEnableReg; |
output [6:0] TxAddrReg; |
output [3:0] TxEndPReg; |
input [10:0] frameNumIn; |
input [7:0] RxPktStatusIn; |
input [3:0] RxPIDIn; |
input [1:0] connectStateIn; |
input SOFSentIn; |
input connEventIn; |
input resumeIntIn; |
input transDoneIn; |
input hostControlSelect; |
input clrTransReq; |
output preambleEn; |
output SOFSync; |
output [1:0] TxLineState; |
output LineDirectControlEn; |
output fullSpeedPol; |
output fullSpeedRate; |
output transReq; |
output isoEn; //enable isochronous mode |
input [15:0] SOFTimer; |
|
wire [3:0] address; |
wire [7:0] dataIn; |
wire writeEn; |
wire strobe_i; |
wire busClk; |
wire rstSyncToBusClk; |
wire usbClk; |
wire rstSyncToUsbClk; |
reg [7:0] dataOut; |
|
reg SOFSentIntOut; |
reg connEventIntOut; |
reg resumeIntOut; |
reg transDoneIntOut; |
|
reg [1:0] TxTransTypeReg; |
reg [1:0] TxTransTypeReg_reg1; |
reg TxSOFEnableReg; |
reg TxSOFEnableReg_reg1; |
reg [6:0] TxAddrReg; |
reg [6:0] TxAddrReg_reg1; |
reg [3:0] TxEndPReg; |
reg [3:0] TxEndPReg_reg1; |
wire [10:0] frameNumIn; |
wire [7:0] RxPktStatusIn; |
wire [3:0] RxPIDIn; |
wire [1:0] connectStateIn; |
|
wire SOFSentIn; |
wire connEventIn; |
wire resumeIntIn; |
wire transDoneIn; |
wire hostControlSelect; |
wire clrTransReq; |
reg preambleEn; |
reg preambleEn_reg1; |
reg SOFSync; |
reg SOFSync_reg1; |
reg [1:0] TxLineState; |
reg [1:0] TxLineState_reg1; |
reg LineDirectControlEn; |
reg LineDirectControlEn_reg1; |
reg fullSpeedPol; |
reg fullSpeedPol_reg1; |
reg fullSpeedRate; |
reg fullSpeedRate_reg1; |
reg transReq; |
reg transReq_reg1; |
reg isoEn; |
reg isoEn_reg1; |
wire [15:0] SOFTimer; |
|
//internal wire and regs |
reg [1:0] TxControlReg; |
reg [4:0] TxLineControlReg; |
reg clrSOFReq; |
reg clrConnEvtReq; |
reg clrResInReq; |
reg clrTransDoneReq; |
reg SOFSentInt; |
reg connEventInt; |
reg resumeInt; |
reg transDoneInt; |
reg [3:0] interruptMaskReg; |
reg setTransReq; |
reg [2:0] resumeIntInExtend; |
reg [2:0] transDoneInExtend; |
reg [2:0] connEventInExtend; |
reg [2:0] SOFSentInExtend; |
reg [2:0] clrTransReqExtend; |
|
//clock domain crossing sync registers |
//STB = Sync To Busclk |
reg [1:0] TxTransTypeRegSTB; |
reg TxSOFEnableRegSTB; |
reg [6:0] TxAddrRegSTB; |
reg [3:0] TxEndPRegSTB; |
reg preambleEnSTB; |
reg SOFSyncSTB; |
reg [1:0] TxLineStateSTB; |
reg LineDirectControlEnSTB; |
reg fullSpeedPolSTB; |
reg fullSpeedRateSTB; |
reg transReqSTB; |
reg isoEnSTB; |
reg [10:0] frameNumInSTB; |
reg [10:0] frameNumInSTB_reg1; |
reg [7:0] RxPktStatusInSTB; |
reg [7:0] RxPktStatusInSTB_reg1; |
reg [3:0] RxPIDInSTB; |
reg [3:0] RxPIDInSTB_reg1; |
reg [1:0] connectStateInSTB; |
reg [1:0] connectStateInSTB_reg1; |
reg [2:0] SOFSentInSTB; |
reg [2:0] connEventInSTB; |
reg [2:0] resumeIntInSTB; |
reg [2:0] transDoneInSTB; |
reg [2:0] clrTransReqSTB; |
reg [15:0] SOFTimerSTB; |
reg [15:0] SOFTimerSTB_reg1; |
|
|
//sync write demux |
always @(posedge busClk) |
begin |
if (rstSyncToBusClk == 1'b1) begin |
isoEnSTB <= 1'b0; |
preambleEnSTB <= 1'b0; |
SOFSyncSTB <= 1'b0; |
TxTransTypeRegSTB <= 2'b00; |
TxLineControlReg <= 5'h00; |
TxSOFEnableRegSTB <= 1'b0; |
TxAddrRegSTB <= 7'h00; |
TxEndPRegSTB <= 4'h0; |
interruptMaskReg <= 4'h0; |
end |
else begin |
clrSOFReq <= 1'b0; |
clrConnEvtReq <= 1'b0; |
clrResInReq <= 1'b0; |
clrTransDoneReq <= 1'b0; |
setTransReq <= 1'b0; |
if (writeEn == 1'b1 && strobe_i == 1'b1 && hostControlSelect == 1'b1) |
begin |
case (address) |
`TX_CONTROL_REG : begin |
isoEnSTB <= dataIn[`ISO_ENABLE_BIT]; |
preambleEnSTB <= dataIn[`PREAMBLE_ENABLE_BIT]; |
SOFSyncSTB <= dataIn[`SOF_SYNC_BIT]; |
setTransReq <= dataIn[`TRANS_REQ_BIT]; |
end |
`TX_TRANS_TYPE_REG : TxTransTypeRegSTB <= dataIn[1:0]; |
`TX_LINE_CONTROL_REG : TxLineControlReg <= dataIn[4:0]; |
`TX_SOF_ENABLE_REG : TxSOFEnableRegSTB <= dataIn[`SOF_EN_BIT]; |
`TX_ADDR_REG : TxAddrRegSTB <= dataIn[6:0]; |
`TX_ENDP_REG : TxEndPRegSTB <= dataIn[3:0]; |
`INTERRUPT_STATUS_REG : begin |
clrSOFReq <= dataIn[`SOF_SENT_BIT]; |
clrConnEvtReq <= dataIn[`CONNECTION_EVENT_BIT]; |
clrResInReq <= dataIn[`RESUME_INT_BIT]; |
clrTransDoneReq <= dataIn[`TRANS_DONE_BIT]; |
end |
`INTERRUPT_MASK_REG : interruptMaskReg <= dataIn[3:0]; |
endcase |
end |
end |
end |
|
//interrupt control |
always @(posedge busClk) |
begin |
if (rstSyncToBusClk == 1'b1) begin |
SOFSentInt <= 1'b0; |
connEventInt <= 1'b0; |
resumeInt <= 1'b0; |
transDoneInt <= 1'b0; |
end |
else begin |
if (SOFSentInSTB[1] == 1'b1 && SOFSentInSTB[0] == 1'b0) |
SOFSentInt <= 1'b1; |
else if (clrSOFReq == 1'b1) |
SOFSentInt <= 1'b0; |
|
if (connEventInSTB[1] == 1'b1 && connEventInSTB[0] == 1'b0) |
connEventInt <= 1'b1; |
else if (clrConnEvtReq == 1'b1) |
connEventInt <= 1'b0; |
|
if (resumeIntInSTB[1] == 1'b1 && resumeIntInSTB[0] == 1'b0) |
resumeInt <= 1'b1; |
else if (clrResInReq == 1'b1) |
resumeInt <= 1'b0; |
|
if (transDoneInSTB[1] == 1'b1 && transDoneInSTB[0] == 1'b0) |
transDoneInt <= 1'b1; |
else if (clrTransDoneReq == 1'b1) |
transDoneInt <= 1'b0; |
end |
end |
|
//mask interrupts |
always @(*) begin |
transDoneIntOut <= transDoneInt & interruptMaskReg[`TRANS_DONE_BIT]; |
resumeIntOut <= resumeInt & interruptMaskReg[`RESUME_INT_BIT]; |
connEventIntOut <= connEventInt & interruptMaskReg[`CONNECTION_EVENT_BIT]; |
SOFSentIntOut <= SOFSentInt & interruptMaskReg[`SOF_SENT_BIT]; |
end |
|
//transaction request set/clear |
//Since 'busClk' can be a higher freq than 'usbClk', |
//'setTransReq' must be delayed with respect to other control signals, thus |
//ensuring that control signals have been clocked through to 'usbClk' clock |
//domain before the transaction request is asserted. |
//Not sure this is required because there is at least two 'usbClk' ticks between |
//detection of 'transReq' and sampling of related control signals. |
always @(posedge busClk) |
begin |
if (rstSyncToBusClk == 1'b1) begin |
transReqSTB <= 1'b0; |
end |
else begin |
if (setTransReq == 1'b1) |
transReqSTB <= 1'b1; |
else if (clrTransReqSTB[1] == 1'b1 && clrTransReqSTB[0] == 1'b0) |
transReqSTB <= 1'b0; |
end |
end |
|
//break out control signals |
always @(*) begin |
TxLineStateSTB <= TxLineControlReg[`TX_LINE_STATE_MSBIT:`TX_LINE_STATE_LSBIT]; |
LineDirectControlEnSTB <= TxLineControlReg[`DIRECT_CONTROL_BIT]; |
fullSpeedPolSTB <= TxLineControlReg[`FULL_SPEED_LINE_POLARITY_BIT]; |
fullSpeedRateSTB <= TxLineControlReg[`FULL_SPEED_LINE_RATE_BIT]; |
end |
|
// async read mux |
always @(*) |
begin |
case (address) |
`TX_CONTROL_REG : dataOut <= {4'b0000, isoEnSTB, preambleEnSTB, SOFSyncSTB, transReqSTB} ; |
`TX_TRANS_TYPE_REG : dataOut <= {6'b000000, TxTransTypeRegSTB}; |
`TX_LINE_CONTROL_REG : dataOut <= {3'b000, TxLineControlReg}; |
`TX_SOF_ENABLE_REG : dataOut <= {7'b0000000, TxSOFEnableRegSTB}; |
`TX_ADDR_REG : dataOut <= {1'b0, TxAddrRegSTB}; |
`TX_ENDP_REG : dataOut <= {4'h0, TxEndPRegSTB}; |
`FRAME_NUM_MSB_REG : dataOut <= {5'b00000, frameNumInSTB[10:8]}; |
`FRAME_NUM_LSB_REG : dataOut <= frameNumInSTB[7:0]; |
`INTERRUPT_STATUS_REG : dataOut <= {4'h0, SOFSentInt, connEventInt, resumeInt, transDoneInt}; |
`INTERRUPT_MASK_REG : dataOut <= {4'h0, interruptMaskReg}; |
`RX_STATUS_REG : dataOut <= RxPktStatusInSTB; |
`RX_PID_REG : dataOut <= {4'b0000, RxPIDInSTB}; |
`RX_CONNECT_STATE_REG : dataOut <= {6'b000000, connectStateInSTB}; |
`HOST_SOF_TIMER_MSB_REG : dataOut <= SOFTimerSTB[15:8]; |
default: dataOut <= 8'h00; |
endcase |
end |
|
//re-sync from busClk to usbClk. |
always @(posedge usbClk) begin |
if (rstSyncToUsbClk == 1'b1) begin |
isoEn <= 1'b0; |
isoEn_reg1 <= 1'b0; |
preambleEn <= 1'b0; |
preambleEn_reg1 <= 1'b0; |
SOFSync <= 1'b0; |
SOFSync_reg1 <= 1'b0; |
TxTransTypeReg <= 2'b00; |
TxTransTypeReg_reg1 <= 2'b00; |
TxSOFEnableReg <= 1'b0; |
TxSOFEnableReg_reg1 <= 1'b0; |
TxAddrReg <= {7{1'b0}}; |
TxAddrReg_reg1 <= {7{1'b0}}; |
TxEndPReg <= 4'h0; |
TxEndPReg_reg1 <= 4'h0; |
TxLineState <= 2'b00; |
TxLineState_reg1 <= 2'b00; |
LineDirectControlEn <= 1'b0; |
LineDirectControlEn_reg1 <= 1'b0; |
fullSpeedPol <= 1'b0; |
fullSpeedPol_reg1 <= 1'b0; |
fullSpeedRate <= 1'b0; |
fullSpeedRate_reg1 <= 1'b0; |
transReq <= 1'b0; |
transReq_reg1 <= 1'b0; |
end |
else begin |
isoEn_reg1 <= isoEnSTB; |
isoEn <= isoEn_reg1; |
preambleEn_reg1 <= preambleEnSTB; |
preambleEn <= preambleEn_reg1; |
SOFSync_reg1 <= SOFSyncSTB; |
SOFSync <= SOFSync_reg1; |
TxTransTypeReg_reg1 <= TxTransTypeRegSTB; |
TxTransTypeReg <= TxTransTypeReg_reg1; |
TxSOFEnableReg_reg1 <= TxSOFEnableRegSTB; |
TxSOFEnableReg <= TxSOFEnableReg_reg1; |
TxAddrReg_reg1 <= TxAddrRegSTB; |
TxAddrReg <= TxAddrReg_reg1; |
TxEndPReg_reg1 <= TxEndPRegSTB; |
TxEndPReg <= TxEndPReg_reg1; |
TxLineState_reg1 <= TxLineStateSTB; |
TxLineState <= TxLineState_reg1; |
LineDirectControlEn_reg1 <= LineDirectControlEnSTB; |
LineDirectControlEn <= LineDirectControlEn_reg1; |
fullSpeedPol_reg1 <= fullSpeedPolSTB; |
fullSpeedPol <= fullSpeedPol_reg1; |
fullSpeedRate_reg1 <= fullSpeedRateSTB; |
fullSpeedRate <= fullSpeedRate_reg1; |
transReq_reg1 <= transReqSTB; |
transReq <= transReq_reg1; |
end |
end |
|
//Extend resumeIntIn etc from 1 tick to 3 ticks |
always @(posedge usbClk) begin |
if (rstSyncToUsbClk == 1'b1) begin |
resumeIntInExtend <= 3'b000; |
transDoneInExtend <= 3'b000; |
connEventInExtend <= 3'b000; |
SOFSentInExtend <= 3'b000; |
clrTransReqExtend <= 3'b000; |
end |
else begin |
if (resumeIntIn == 1'b1) |
resumeIntInExtend <= 3'b111; |
else |
resumeIntInExtend <= {1'b0, resumeIntInExtend[2:1]}; |
if (transDoneIn == 1'b1) |
transDoneInExtend <= 3'b111; |
else |
transDoneInExtend <= {1'b0, transDoneInExtend[2:1]}; |
if (connEventIn == 1'b1) |
connEventInExtend <= 3'b111; |
else |
connEventInExtend <= {1'b0, connEventInExtend[2:1]}; |
if (SOFSentIn == 1'b1) |
SOFSentInExtend <= 3'b111; |
else |
SOFSentInExtend <= {1'b0, SOFSentInExtend[2:1]}; |
if (clrTransReq == 1'b1) |
clrTransReqExtend <= 3'b111; |
else |
clrTransReqExtend <= {1'b0, clrTransReqExtend[2:1]}; |
end |
end |
|
//re-sync from usbClk to busClk. Since 'clrTransReq', 'transDoneIn' etc are only asserted |
//for 3 'usbClk' ticks, busClk freq must be greater than or equal to usbClk/3 freq |
always @(posedge busClk) begin |
if (rstSyncToBusClk == 1'b1) begin |
SOFSentInSTB <= 3'b000; |
connEventInSTB <= 3'b000; |
resumeIntInSTB <= 3'b000; |
transDoneInSTB <= 3'b000; |
clrTransReqSTB <= 3'b000; |
frameNumInSTB <= {11{1'b0}}; |
frameNumInSTB_reg1 <= {11{1'b0}}; |
RxPktStatusInSTB <= 8'h00; |
RxPktStatusInSTB_reg1 <= 8'h00; |
RxPIDInSTB <= 4'h0; |
RxPIDInSTB_reg1 <= 4'h0; |
connectStateInSTB <= 2'b00; |
connectStateInSTB_reg1 <= 2'b00; |
SOFTimerSTB <= 16'h0000; |
SOFTimerSTB_reg1 <= 16'h0000; |
end |
else begin |
frameNumInSTB_reg1 <= frameNumIn; |
frameNumInSTB <= frameNumInSTB_reg1; |
RxPktStatusInSTB_reg1 <= RxPktStatusIn; |
RxPktStatusInSTB <= RxPktStatusInSTB_reg1; |
RxPIDInSTB_reg1 <= RxPIDIn; |
RxPIDInSTB <= RxPIDInSTB_reg1; |
connectStateInSTB_reg1 <= connectStateIn; |
connectStateInSTB <= connectStateInSTB_reg1; |
SOFSentInSTB <= {SOFSentInExtend[0], SOFSentInSTB[2:1]}; |
connEventInSTB <= {connEventInExtend[0], connEventInSTB[2:1]}; |
resumeIntInSTB <= {resumeIntInExtend[0], resumeIntInSTB[2:1]}; |
transDoneInSTB <= {transDoneInExtend[0], transDoneInSTB[2:1]}; |
clrTransReqSTB <= {clrTransReqExtend[0], clrTransReqSTB[2:1]}; |
//FIXME. It is not safe to pass 'SOFTimer' multi-bit signal between clock domains this way |
//All the other multi-bit signals will be static at the time that they are |
//read, but 'SOFTimer' will not be static. |
SOFTimerSTB_reg1 <= SOFTimer; |
SOFTimerSTB <= SOFTimerSTB_reg1; |
end |
end |
|
|
endmodule |
/verilog/usbhostslave/USBTxWireArbiter.v
0,0 → 1,213
|
// File : ../RTL/serialInterfaceEngine/usbTxWireArbiter.v |
// Generated : 11/10/06 05:37:24 |
// From : ../RTL/serialInterfaceEngine/usbTxWireArbiter.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// usbTxWireArbiter |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_constants_h.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
|
|
module USBTxWireArbiter (SIETxCtrl, SIETxData, SIETxFSRate, SIETxGnt, SIETxReq, SIETxWEn, TxBits, TxCtl, TxFSRate, USBWireRdyIn, USBWireRdyOut, USBWireWEn, clk, prcTxByteCtrl, prcTxByteData, prcTxByteFSRate, prcTxByteGnt, prcTxByteReq, prcTxByteWEn, rst); |
input SIETxCtrl; |
input [1:0] SIETxData; |
input SIETxFSRate; |
input SIETxReq; |
input SIETxWEn; |
input USBWireRdyIn; |
input clk; |
input prcTxByteCtrl; |
input [1:0] prcTxByteData; |
input prcTxByteFSRate; |
input prcTxByteReq; |
input prcTxByteWEn; |
input rst; |
output SIETxGnt; |
output [1:0] TxBits; |
output TxCtl; |
output TxFSRate; |
output USBWireRdyOut; |
output USBWireWEn; |
output prcTxByteGnt; |
|
wire SIETxCtrl; |
wire [1:0] SIETxData; |
wire SIETxFSRate; |
reg SIETxGnt, next_SIETxGnt; |
wire SIETxReq; |
wire SIETxWEn; |
reg [1:0] TxBits, next_TxBits; |
reg TxCtl, next_TxCtl; |
reg TxFSRate, next_TxFSRate; |
wire USBWireRdyIn; |
reg USBWireRdyOut, next_USBWireRdyOut; |
reg USBWireWEn, next_USBWireWEn; |
wire clk; |
wire prcTxByteCtrl; |
wire [1:0] prcTxByteData; |
wire prcTxByteFSRate; |
reg prcTxByteGnt, next_prcTxByteGnt; |
wire prcTxByteReq; |
wire prcTxByteWEn; |
wire rst; |
|
// diagram signals declarations |
reg muxSIENotPTXB, next_muxSIENotPTXB; |
|
// BINARY ENCODED state machine: txWireArb |
// State codes definitions: |
`define START_TARB 2'b00 |
`define TARB_WAIT_REQ 2'b01 |
`define PTXB_ACT 2'b10 |
`define SIE_TX_ACT 2'b11 |
|
reg [1:0] CurrState_txWireArb; |
reg [1:0] NextState_txWireArb; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
// processTxByte/SIETransmitter mux |
always @(USBWireRdyIn) |
begin |
USBWireRdyOut <= USBWireRdyIn; |
end |
always @(muxSIENotPTXB or SIETxWEn or SIETxData or |
SIETxCtrl or prcTxByteWEn or prcTxByteData or prcTxByteCtrl or |
SIETxFSRate or prcTxByteFSRate) |
begin |
if (muxSIENotPTXB == 1'b1) |
begin |
USBWireWEn <= SIETxWEn; |
TxBits <= SIETxData; |
TxCtl <= SIETxCtrl; |
TxFSRate <= SIETxFSRate; |
end |
else |
begin |
USBWireWEn <= prcTxByteWEn; |
TxBits <= prcTxByteData; |
TxCtl <= prcTxByteCtrl; |
TxFSRate <= prcTxByteFSRate; |
end |
end |
|
//-------------------------------------------------------------------- |
// Machine: txWireArb |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (prcTxByteReq or SIETxReq or prcTxByteGnt or muxSIENotPTXB or SIETxGnt or CurrState_txWireArb) |
begin : txWireArb_NextState |
NextState_txWireArb <= CurrState_txWireArb; |
// Set default values for outputs and signals |
next_prcTxByteGnt <= prcTxByteGnt; |
next_muxSIENotPTXB <= muxSIENotPTXB; |
next_SIETxGnt <= SIETxGnt; |
case (CurrState_txWireArb) |
`START_TARB: |
NextState_txWireArb <= `TARB_WAIT_REQ; |
`TARB_WAIT_REQ: |
if (prcTxByteReq == 1'b1) |
begin |
NextState_txWireArb <= `PTXB_ACT; |
next_prcTxByteGnt <= 1'b1; |
next_muxSIENotPTXB <= 1'b0; |
end |
else if (SIETxReq == 1'b1) |
begin |
NextState_txWireArb <= `SIE_TX_ACT; |
next_SIETxGnt <= 1'b1; |
next_muxSIENotPTXB <= 1'b1; |
end |
`PTXB_ACT: |
if (prcTxByteReq == 1'b0) |
begin |
NextState_txWireArb <= `TARB_WAIT_REQ; |
next_prcTxByteGnt <= 1'b0; |
end |
`SIE_TX_ACT: |
if (SIETxReq == 1'b0) |
begin |
NextState_txWireArb <= `TARB_WAIT_REQ; |
next_SIETxGnt <= 1'b0; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : txWireArb_CurrentState |
if (rst) |
CurrState_txWireArb <= `START_TARB; |
else |
CurrState_txWireArb <= NextState_txWireArb; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : txWireArb_RegOutput |
if (rst) |
begin |
muxSIENotPTXB <= 1'b0; |
prcTxByteGnt <= 1'b0; |
SIETxGnt <= 1'b0; |
end |
else |
begin |
muxSIENotPTXB <= next_muxSIENotPTXB; |
prcTxByteGnt <= next_prcTxByteGnt; |
SIETxGnt <= next_SIETxGnt; |
end |
end |
|
endmodule |
/verilog/usbhostslave/slaveDirectControl.v
0,0 → 1,197
|
// File : ../RTL/slaveController/slaveDirectcontrol.v |
// Generated : 11/10/06 05:37:25 |
// From : ../RTL/slaveController/slaveDirectcontrol.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// slaveDirectControl |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
module slaveDirectControl (SCTxPortCntl, SCTxPortData, SCTxPortGnt, SCTxPortRdy, SCTxPortReq, SCTxPortWEn, clk, directControlEn, directControlLineState, rst); |
input SCTxPortGnt; |
input SCTxPortRdy; |
input clk; |
input directControlEn; |
input [1:0] directControlLineState; |
input rst; |
output [7:0] SCTxPortCntl; |
output [7:0] SCTxPortData; |
output SCTxPortReq; |
output SCTxPortWEn; |
|
reg [7:0] SCTxPortCntl, next_SCTxPortCntl; |
reg [7:0] SCTxPortData, next_SCTxPortData; |
wire SCTxPortGnt; |
wire SCTxPortRdy; |
reg SCTxPortReq, next_SCTxPortReq; |
reg SCTxPortWEn, next_SCTxPortWEn; |
wire clk; |
wire directControlEn; |
wire [1:0] directControlLineState; |
wire rst; |
|
// BINARY ENCODED state machine: slvDrctCntl |
// State codes definitions: |
`define START_SDC 3'b000 |
`define CHK_DRCT_CNTL 3'b001 |
`define DRCT_CNTL_WAIT_GNT 3'b010 |
`define DRCT_CNTL_CHK_LOOP 3'b011 |
`define DRCT_CNTL_WAIT_RDY 3'b100 |
`define IDLE_FIN 3'b101 |
`define IDLE_WAIT_GNT 3'b110 |
`define IDLE_WAIT_RDY 3'b111 |
|
reg [2:0] CurrState_slvDrctCntl; |
reg [2:0] NextState_slvDrctCntl; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
// diagram ACTION |
|
//-------------------------------------------------------------------- |
// Machine: slvDrctCntl |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (directControlLineState or directControlEn or SCTxPortGnt or SCTxPortRdy or SCTxPortReq or SCTxPortWEn or SCTxPortData or SCTxPortCntl or CurrState_slvDrctCntl) |
begin : slvDrctCntl_NextState |
NextState_slvDrctCntl <= CurrState_slvDrctCntl; |
// Set default values for outputs and signals |
next_SCTxPortReq <= SCTxPortReq; |
next_SCTxPortWEn <= SCTxPortWEn; |
next_SCTxPortData <= SCTxPortData; |
next_SCTxPortCntl <= SCTxPortCntl; |
case (CurrState_slvDrctCntl) |
`START_SDC: |
NextState_slvDrctCntl <= `CHK_DRCT_CNTL; |
`CHK_DRCT_CNTL: |
if (directControlEn == 1'b1) |
begin |
NextState_slvDrctCntl <= `DRCT_CNTL_WAIT_GNT; |
next_SCTxPortReq <= 1'b1; |
end |
else |
begin |
NextState_slvDrctCntl <= `IDLE_WAIT_GNT; |
next_SCTxPortReq <= 1'b1; |
end |
`DRCT_CNTL_WAIT_GNT: |
if (SCTxPortGnt == 1'b1) |
NextState_slvDrctCntl <= `DRCT_CNTL_WAIT_RDY; |
`DRCT_CNTL_CHK_LOOP: |
begin |
next_SCTxPortWEn <= 1'b0; |
if (directControlEn == 1'b0) |
begin |
NextState_slvDrctCntl <= `CHK_DRCT_CNTL; |
next_SCTxPortReq <= 1'b0; |
end |
else |
NextState_slvDrctCntl <= `DRCT_CNTL_WAIT_RDY; |
end |
`DRCT_CNTL_WAIT_RDY: |
if (SCTxPortRdy == 1'b1) |
begin |
NextState_slvDrctCntl <= `DRCT_CNTL_CHK_LOOP; |
next_SCTxPortWEn <= 1'b1; |
next_SCTxPortData <= {6'b000000, directControlLineState}; |
next_SCTxPortCntl <= `TX_DIRECT_CONTROL; |
end |
`IDLE_FIN: |
begin |
next_SCTxPortWEn <= 1'b0; |
next_SCTxPortReq <= 1'b0; |
NextState_slvDrctCntl <= `CHK_DRCT_CNTL; |
end |
`IDLE_WAIT_GNT: |
if (SCTxPortGnt == 1'b1) |
NextState_slvDrctCntl <= `IDLE_WAIT_RDY; |
`IDLE_WAIT_RDY: |
if (SCTxPortRdy == 1'b1) |
begin |
NextState_slvDrctCntl <= `IDLE_FIN; |
next_SCTxPortWEn <= 1'b1; |
next_SCTxPortData <= 8'h00; |
next_SCTxPortCntl <= `TX_IDLE; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : slvDrctCntl_CurrentState |
if (rst) |
CurrState_slvDrctCntl <= `START_SDC; |
else |
CurrState_slvDrctCntl <= NextState_slvDrctCntl; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : slvDrctCntl_RegOutput |
if (rst) |
begin |
SCTxPortCntl <= 8'h00; |
SCTxPortData <= 8'h00; |
SCTxPortWEn <= 1'b0; |
SCTxPortReq <= 1'b0; |
end |
else |
begin |
SCTxPortCntl <= next_SCTxPortCntl; |
SCTxPortData <= next_SCTxPortData; |
SCTxPortWEn <= next_SCTxPortWEn; |
SCTxPortReq <= next_SCTxPortReq; |
end |
end |
|
endmodule |
/verilog/usbhostslave/readUSBWireData.v
0,0 → 1,274
////////////////////////////////////////////////////////////////////// |
//// //// |
//// readUSBWireData.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// This module reads data from the differential USB data lines |
//// and writes into a 4 entry FIFO. The data is read from |
//// the fifo and output from the module when the higher level |
//// state machine is ready to receive the data. |
//// This module must recover the clock phase from the incoming |
//// USB data. 'sampleCnt' is reset to zero whenever a RX data |
//// edge is detected. Note that due to metastability the data |
//// at the edge may not be registered correctly, but this does |
//// not matter. All that matters is that an edge was detected. The |
//// data will be accurately sampled in the middle of the USB bit |
//// period without metastability issues. |
//// After the edge detect, 'sampleCnt' is incremented at every clock |
//// tick, and when it indicates the middle of a USB bit period |
//// the RX data is sampled and written to the input buffer. |
//// Single clock tick adjustments to 'sampleCnt' can be made at |
//// every RX data edge detect without double sampling the incoming |
//// data. However, the first RX data bit in a packet may cause |
//// 'sampleCnt' to be adjusted by a value greater than a single |
//// clock tick, and this can result in double sampling of the |
//// first data bit a RX packet. This |
//// double sampled data must be rejected by the higher level module. |
//// This is achieved by |
//// qualifying the outgoing data with 'RxWireActive'. Thus |
//// the first data bit in a RX packet may be double sampled |
//// as the clock recovery mechanism synchronizes to 'RxBitsIn' |
//// but the double sampled data will be rejected by the higher |
//// level module. |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
module readUSBWireData (RxBitsIn, RxDataInTick, RxBitsOut, SIERxRdyIn, SIERxWEn, fullSpeedRate, TxWireActiveDrive, clk, rst, noActivityTimeOut, RxWireActive, noActivityTimeOutEnable); |
input [1:0] RxBitsIn; |
output RxDataInTick; |
input SIERxRdyIn; |
input clk; |
input fullSpeedRate; |
input rst; |
input TxWireActiveDrive; |
output [1:0] RxBitsOut; |
output SIERxWEn; |
output noActivityTimeOut; |
output RxWireActive; |
input noActivityTimeOutEnable; |
|
wire [1:0] RxBitsIn; |
reg RxDataInTick; |
wire SIERxRdyIn; |
wire clk; |
wire fullSpeedRate; |
wire rst; |
reg [1:0] RxBitsOut; |
reg SIERxWEn; |
reg noActivityTimeOut; |
reg RxWireActive; |
wire noActivityTimeOutEnable; |
|
// local registers |
reg [2:0]buffer0; |
reg [2:0]buffer1; |
reg [2:0]buffer2; |
reg [2:0]buffer3; |
reg [2:0]bufferCnt; |
reg [1:0]bufferInIndex; |
reg [1:0]bufferOutIndex; |
reg decBufferCnt; |
reg [4:0]sampleCnt; |
reg incBufferCnt; |
reg [1:0]oldRxBitsIn; |
reg [1:0] RxBitsInReg; |
reg [15:0] timeOutCnt; |
reg [7:0] rxActiveCnt; |
reg RxWireEdgeDetect; |
reg RxWireActiveReg; |
reg RxWireActiveReg2; |
reg [1:0] RxBitsInSyncReg1; |
reg [1:0] RxBitsInSyncReg2; |
|
// buffer output state machine state codes: |
`define WAIT_BUFFER_NOT_EMPTY 2'b00 |
`define WAIT_SIE_RX_READY 2'b01 |
`define SIE_RX_WRITE 2'b10 |
|
// re-synchronize incoming bits |
always @(posedge clk) begin |
RxBitsInSyncReg1 <= RxBitsIn; |
RxBitsInSyncReg2 <= RxBitsInSyncReg1; |
end |
|
reg [1:0] bufferOutStMachCurrState; |
|
|
always @(posedge clk) begin |
if (rst == 1'b1) |
begin |
bufferCnt <= 3'b000; |
end |
else begin |
if (incBufferCnt == 1'b1 && decBufferCnt == 1'b0) |
bufferCnt <= bufferCnt + 1'b1; |
else if (incBufferCnt == 1'b0 && decBufferCnt == 1'b1) |
bufferCnt <= bufferCnt - 1'b1; |
end |
end |
|
|
|
//Perform line rate clock recovery |
//Recover the wire data, and store data to buffer |
always @(posedge clk) begin |
if (rst == 1'b1) |
begin |
sampleCnt <= 5'b00000; |
incBufferCnt <= 1'b0; |
bufferInIndex <= 2'b00; |
buffer0 <= 3'b000; |
buffer1 <= 3'b000; |
buffer2 <= 3'b000; |
buffer3 <= 3'b000; |
RxDataInTick <= 1'b0; |
RxWireEdgeDetect <= 1'b0; |
RxWireActiveReg <= 1'b0; |
RxWireActiveReg2 <= 1'b0; |
end |
else begin |
RxWireActiveReg2 <= RxWireActiveReg; //Delay 'RxWireActiveReg' until after 'sampleCnt' has been reset |
RxBitsInReg <= RxBitsInSyncReg2; |
oldRxBitsIn <= RxBitsInReg; |
incBufferCnt <= 1'b0; //default value |
if ( (TxWireActiveDrive == 1'b0) && (RxBitsInSyncReg2 != RxBitsInReg)) begin //if edge detected then |
sampleCnt <= 5'b00000; |
RxWireEdgeDetect <= 1'b1; // flag receive activity |
RxWireActiveReg <= 1'b1; |
rxActiveCnt <= 8'h00; |
end |
else begin |
sampleCnt <= sampleCnt + 1'b1; |
RxWireEdgeDetect <= 1'b0; |
rxActiveCnt <= rxActiveCnt + 1'b1; |
//clear 'RxWireActiveReg' if no RX transitions for RX_EDGE_DET_TOUT USB bit periods |
if ( (fullSpeedRate == 1'b1 && rxActiveCnt == `RX_EDGE_DET_TOUT * `FS_OVER_SAMPLE_RATE) |
|| (fullSpeedRate == 1'b0 && rxActiveCnt == `RX_EDGE_DET_TOUT * `LS_OVER_SAMPLE_RATE) ) |
RxWireActiveReg <= 1'b0; |
end |
if ( (fullSpeedRate == 1'b1 && sampleCnt[1:0] == 2'b10) || (fullSpeedRate == 1'b0 && sampleCnt == 5'b10000) ) |
begin |
RxDataInTick <= !RxDataInTick; |
if (TxWireActiveDrive != 1'b1) //do not read wire data when transmitter is active |
begin |
incBufferCnt <= 1'b1; |
bufferInIndex <= bufferInIndex + 1'b1; |
case (bufferInIndex) |
2'b00 : buffer0 <= {RxWireActiveReg2, oldRxBitsIn}; |
2'b01 : buffer1 <= {RxWireActiveReg2, oldRxBitsIn}; |
2'b10 : buffer2 <= {RxWireActiveReg2, oldRxBitsIn}; |
2'b11 : buffer3 <= {RxWireActiveReg2, oldRxBitsIn}; |
endcase |
end |
end |
end |
end |
|
|
|
//read from buffer, and output to SIEReceiver |
always @(posedge clk) begin |
if (rst == 1'b1) |
begin |
decBufferCnt <= 1'b0; |
bufferOutIndex <= 2'b00; |
RxBitsOut <= 2'b00; |
SIERxWEn <= 1'b0; |
bufferOutStMachCurrState <= `WAIT_BUFFER_NOT_EMPTY; |
end |
else begin |
case (bufferOutStMachCurrState) |
`WAIT_BUFFER_NOT_EMPTY: |
begin |
if (bufferCnt != 3'b000) |
bufferOutStMachCurrState <= `WAIT_SIE_RX_READY; |
end |
`WAIT_SIE_RX_READY: |
begin |
if (SIERxRdyIn == 1'b1) |
begin |
SIERxWEn <= 1'b1; |
bufferOutStMachCurrState <= `SIE_RX_WRITE; |
decBufferCnt <= 1'b1; |
bufferOutIndex <= bufferOutIndex + 1'b1; |
case (bufferOutIndex) |
2'b00 : begin RxBitsOut <= buffer0[1:0]; RxWireActive <= buffer0[2]; end |
2'b01 : begin RxBitsOut <= buffer1[1:0]; RxWireActive <= buffer1[2]; end |
2'b10 : begin RxBitsOut <= buffer2[1:0]; RxWireActive <= buffer2[2]; end |
2'b11 : begin RxBitsOut <= buffer3[1:0]; RxWireActive <= buffer3[2]; end |
endcase |
end |
end |
`SIE_RX_WRITE: |
begin |
SIERxWEn <= 1'b0; |
decBufferCnt <= 1'b0; |
bufferOutStMachCurrState <= `WAIT_BUFFER_NOT_EMPTY; |
end |
endcase |
end |
end |
|
//generate 'noActivityTimeOut' pulse if no tx or rx activity for RX_PACKET_TOUT USB bit periods |
//'noActivityTimeOut' pulse can only be generated when the host or slave getPacket |
//process enables via 'noActivityTimeOutEnable' signal |
//'noActivityTimeOut' pulse is used by host and slave getPacket processes to determine if |
//there has been a response time out. |
always @(posedge clk) begin |
if (rst) begin |
timeOutCnt <= 16'h0000; |
noActivityTimeOut <= 1'b0; |
end |
else begin |
if (TxWireActiveDrive == 1'b1 || RxWireEdgeDetect == 1'b1 || noActivityTimeOutEnable == 1'b0) |
timeOutCnt <= 16'h0000; |
else |
timeOutCnt <= timeOutCnt + 1'b1; |
if ( (fullSpeedRate == 1'b1 && timeOutCnt == `RX_PACKET_TOUT * `FS_OVER_SAMPLE_RATE) |
|| (fullSpeedRate == 1'b0 && timeOutCnt == `RX_PACKET_TOUT * `LS_OVER_SAMPLE_RATE) ) |
noActivityTimeOut <= 1'b1; |
else |
noActivityTimeOut <= 1'b0; |
end |
end |
|
|
endmodule |
/verilog/usbhostslave/getPacket.v
0,0 → 1,375
|
// File : ../RTL/hostController/getpacket.v |
// Generated : 11/10/06 05:37:20 |
// From : ../RTL/hostController/getpacket.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// getpacket |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
`include "usbhostslave_serialinterfaceengine_h.v" |
`include "usbhostslave_constants_h.v" |
|
module getPacket (RXDataIn, RXDataValid, RXFifoData, RXFifoFull, RXFifoWEn, RXPacketRdy, RXPktStatus, RXStreamStatusIn, RxPID, SIERxTimeOut, SIERxTimeOutEn, clk, getPacketEn, rst); |
input [7:0] RXDataIn; |
input RXDataValid; |
input RXFifoFull; |
input [7:0] RXStreamStatusIn; |
input SIERxTimeOut; // Single cycle pulse |
input clk; |
input getPacketEn; |
input rst; |
output [7:0] RXFifoData; |
output RXFifoWEn; |
output RXPacketRdy; |
output [7:0] RXPktStatus; |
output [3:0] RxPID; |
output SIERxTimeOutEn; |
|
wire [7:0] RXDataIn; |
wire RXDataValid; |
reg [7:0] RXFifoData, next_RXFifoData; |
wire RXFifoFull; |
reg RXFifoWEn, next_RXFifoWEn; |
reg RXPacketRdy, next_RXPacketRdy; |
reg [7:0] RXPktStatus; |
wire [7:0] RXStreamStatusIn; |
reg [3:0] RxPID, next_RxPID; |
wire SIERxTimeOut; |
reg SIERxTimeOutEn, next_SIERxTimeOutEn; |
wire clk; |
wire getPacketEn; |
wire rst; |
|
// diagram signals declarations |
reg ACKRxed, next_ACKRxed; |
reg CRCError, next_CRCError; |
reg NAKRxed, next_NAKRxed; |
reg [7:0]RXByteOld, next_RXByteOld; |
reg [7:0]RXByteOldest, next_RXByteOldest; |
reg [7:0]RXByte, next_RXByte; |
reg RXOverflow, next_RXOverflow; |
reg [7:0]RXStreamStatus, next_RXStreamStatus; |
reg RXTimeOut, next_RXTimeOut; |
reg bitStuffError, next_bitStuffError; |
reg dataSequence, next_dataSequence; |
reg stallRxed, next_stallRxed; |
|
// BINARY ENCODED state machine: getPkt |
// State codes definitions: |
`define PROC_PKT_CHK_PID 5'b00000 |
`define PROC_PKT_HS 5'b00001 |
`define PROC_PKT_DATA_W_D1 5'b00010 |
`define PROC_PKT_DATA_CHK_D1 5'b00011 |
`define PROC_PKT_DATA_W_D2 5'b00100 |
`define PROC_PKT_DATA_FIN 5'b00101 |
`define PROC_PKT_DATA_CHK_D2 5'b00110 |
`define PROC_PKT_DATA_W_D3 5'b00111 |
`define PROC_PKT_DATA_CHK_D3 5'b01000 |
`define PROC_PKT_DATA_LOOP_CHK_FIFO 5'b01001 |
`define PROC_PKT_DATA_LOOP_FIFO_FULL 5'b01010 |
`define PROC_PKT_DATA_LOOP_W_D 5'b01011 |
`define START_GP 5'b01100 |
`define WAIT_PKT 5'b01101 |
`define CHK_PKT_START 5'b01110 |
`define WAIT_EN 5'b01111 |
`define PKT_RDY 5'b10000 |
`define PROC_PKT_DATA_LOOP_DELAY 5'b10001 |
|
reg [4:0] CurrState_getPkt; |
reg [4:0] NextState_getPkt; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
always @ |
(CRCError or bitStuffError or |
RXOverflow or RXTimeOut or |
NAKRxed or stallRxed or |
ACKRxed or dataSequence) |
begin |
RXPktStatus <= { |
dataSequence, ACKRxed, |
stallRxed, NAKRxed, |
RXTimeOut, RXOverflow, |
bitStuffError, CRCError}; |
end |
|
//-------------------------------------------------------------------- |
// Machine: getPkt |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (RXDataIn or RXStreamStatusIn or RXByte or RXByteOldest or RXByteOld or SIERxTimeOut or RXDataValid or RXStreamStatus or getPacketEn or RXFifoFull or CRCError or bitStuffError or RXOverflow or RXTimeOut or NAKRxed or stallRxed or ACKRxed or dataSequence or SIERxTimeOutEn or RxPID or RXPacketRdy or RXFifoWEn or RXFifoData or CurrState_getPkt) |
begin : getPkt_NextState |
NextState_getPkt <= CurrState_getPkt; |
// Set default values for outputs and signals |
next_CRCError <= CRCError; |
next_bitStuffError <= bitStuffError; |
next_RXOverflow <= RXOverflow; |
next_RXTimeOut <= RXTimeOut; |
next_NAKRxed <= NAKRxed; |
next_stallRxed <= stallRxed; |
next_ACKRxed <= ACKRxed; |
next_dataSequence <= dataSequence; |
next_SIERxTimeOutEn <= SIERxTimeOutEn; |
next_RXByte <= RXByte; |
next_RXStreamStatus <= RXStreamStatus; |
next_RxPID <= RxPID; |
next_RXPacketRdy <= RXPacketRdy; |
next_RXByteOldest <= RXByteOldest; |
next_RXByteOld <= RXByteOld; |
next_RXFifoWEn <= RXFifoWEn; |
next_RXFifoData <= RXFifoData; |
case (CurrState_getPkt) |
`START_GP: |
NextState_getPkt <= `WAIT_EN; |
`WAIT_PKT: |
begin |
next_CRCError <= 1'b0; |
next_bitStuffError <= 1'b0; |
next_RXOverflow <= 1'b0; |
next_RXTimeOut <= 1'b0; |
next_NAKRxed <= 1'b0; |
next_stallRxed <= 1'b0; |
next_ACKRxed <= 1'b0; |
next_dataSequence <= 1'b0; |
next_SIERxTimeOutEn <= 1'b1; |
if (SIERxTimeOut == 1'b1) |
begin |
NextState_getPkt <= `PKT_RDY; |
next_RXTimeOut <= 1'b1; |
end |
else if (RXDataValid == 1'b1) |
begin |
NextState_getPkt <= `CHK_PKT_START; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
end |
`CHK_PKT_START: |
if (RXStreamStatus == `RX_PACKET_START) |
begin |
NextState_getPkt <= `PROC_PKT_CHK_PID; |
next_RxPID <= RXByte[3:0]; |
end |
else |
begin |
NextState_getPkt <= `PKT_RDY; |
next_RXTimeOut <= 1'b1; |
end |
`WAIT_EN: |
begin |
next_RXPacketRdy <= 1'b0; |
next_SIERxTimeOutEn <= 1'b0; |
if (getPacketEn == 1'b1) |
NextState_getPkt <= `WAIT_PKT; |
end |
`PKT_RDY: |
begin |
next_RXPacketRdy <= 1'b1; |
NextState_getPkt <= `WAIT_EN; |
end |
`PROC_PKT_CHK_PID: |
if (RXByte[1:0] == `HANDSHAKE) |
NextState_getPkt <= `PROC_PKT_HS; |
else if (RXByte[1:0] == `DATA) |
NextState_getPkt <= `PROC_PKT_DATA_W_D1; |
else |
NextState_getPkt <= `PKT_RDY; |
`PROC_PKT_HS: |
if (RXDataValid == 1'b1) |
begin |
NextState_getPkt <= `PKT_RDY; |
next_RXOverflow <= RXDataIn[`RX_OVERFLOW_BIT]; |
next_NAKRxed <= RXDataIn[`NAK_RXED_BIT]; |
next_stallRxed <= RXDataIn[`STALL_RXED_BIT]; |
next_ACKRxed <= RXDataIn[`ACK_RXED_BIT]; |
end |
`PROC_PKT_DATA_W_D1: |
if (RXDataValid == 1'b1) |
begin |
NextState_getPkt <= `PROC_PKT_DATA_CHK_D1; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
`PROC_PKT_DATA_CHK_D1: |
if (RXStreamStatus == `RX_PACKET_STREAM) |
begin |
NextState_getPkt <= `PROC_PKT_DATA_W_D2; |
next_RXByteOldest <= RXByte; |
end |
else |
NextState_getPkt <= `PROC_PKT_DATA_FIN; |
`PROC_PKT_DATA_W_D2: |
if (RXDataValid == 1'b1) |
begin |
NextState_getPkt <= `PROC_PKT_DATA_CHK_D2; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
`PROC_PKT_DATA_FIN: |
begin |
next_CRCError <= RXByte[`CRC_ERROR_BIT]; |
next_bitStuffError <= RXByte[`BIT_STUFF_ERROR_BIT]; |
next_dataSequence <= RXByte[`DATA_SEQUENCE_BIT]; |
NextState_getPkt <= `PKT_RDY; |
end |
`PROC_PKT_DATA_CHK_D2: |
if (RXStreamStatus == `RX_PACKET_STREAM) |
begin |
NextState_getPkt <= `PROC_PKT_DATA_W_D3; |
next_RXByteOld <= RXByte; |
end |
else |
NextState_getPkt <= `PROC_PKT_DATA_FIN; |
`PROC_PKT_DATA_W_D3: |
if (RXDataValid == 1'b1) |
begin |
NextState_getPkt <= `PROC_PKT_DATA_CHK_D3; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
`PROC_PKT_DATA_CHK_D3: |
if (RXStreamStatus == `RX_PACKET_STREAM) |
NextState_getPkt <= `PROC_PKT_DATA_LOOP_CHK_FIFO; |
else |
NextState_getPkt <= `PROC_PKT_DATA_FIN; |
`PROC_PKT_DATA_LOOP_CHK_FIFO: |
if (RXFifoFull == 1'b1) |
begin |
NextState_getPkt <= `PROC_PKT_DATA_LOOP_FIFO_FULL; |
next_RXOverflow <= 1'b1; |
end |
else |
begin |
NextState_getPkt <= `PROC_PKT_DATA_LOOP_W_D; |
next_RXFifoWEn <= 1'b1; |
next_RXFifoData <= RXByteOldest; |
next_RXByteOldest <= RXByteOld; |
next_RXByteOld <= RXByte; |
end |
`PROC_PKT_DATA_LOOP_FIFO_FULL: |
NextState_getPkt <= `PROC_PKT_DATA_LOOP_W_D; |
`PROC_PKT_DATA_LOOP_W_D: |
begin |
next_RXFifoWEn <= 1'b0; |
if ((RXDataValid == 1'b1) && (RXStreamStatusIn == `RX_PACKET_STREAM)) |
begin |
NextState_getPkt <= `PROC_PKT_DATA_LOOP_DELAY; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
else if (RXDataValid == 1'b1) |
begin |
NextState_getPkt <= `PROC_PKT_DATA_FIN; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
end |
`PROC_PKT_DATA_LOOP_DELAY: |
NextState_getPkt <= `PROC_PKT_DATA_LOOP_CHK_FIFO; |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : getPkt_CurrentState |
if (rst) |
CurrState_getPkt <= `START_GP; |
else |
CurrState_getPkt <= NextState_getPkt; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : getPkt_RegOutput |
if (rst) |
begin |
RXByteOld <= 8'h00; |
RXByteOldest <= 8'h00; |
CRCError <= 1'b0; |
bitStuffError <= 1'b0; |
RXOverflow <= 1'b0; |
RXTimeOut <= 1'b0; |
NAKRxed <= 1'b0; |
stallRxed <= 1'b0; |
ACKRxed <= 1'b0; |
dataSequence <= 1'b0; |
RXByte <= 8'h00; |
RXStreamStatus <= 8'h00; |
RXPacketRdy <= 1'b0; |
RXFifoWEn <= 1'b0; |
RXFifoData <= 8'h00; |
RxPID <= 4'h0; |
SIERxTimeOutEn <= 1'b0; |
end |
else |
begin |
RXByteOld <= next_RXByteOld; |
RXByteOldest <= next_RXByteOldest; |
CRCError <= next_CRCError; |
bitStuffError <= next_bitStuffError; |
RXOverflow <= next_RXOverflow; |
RXTimeOut <= next_RXTimeOut; |
NAKRxed <= next_NAKRxed; |
stallRxed <= next_stallRxed; |
ACKRxed <= next_ACKRxed; |
dataSequence <= next_dataSequence; |
RXByte <= next_RXByte; |
RXStreamStatus <= next_RXStreamStatus; |
RXPacketRdy <= next_RXPacketRdy; |
RXFifoWEn <= next_RXFifoWEn; |
RXFifoData <= next_RXFifoData; |
RxPID <= next_RxPID; |
SIERxTimeOutEn <= next_SIERxTimeOutEn; |
end |
end |
|
endmodule |
/verilog/usbhostslave/RxfifoBI.v
0,0 → 1,154
////////////////////////////////////////////////////////////////////// |
//// //// |
//// RxfifoBI.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_wishbonebus_h.v" |
|
module RxfifoBI ( |
address, |
writeEn, |
strobe_i, |
busClk, |
usbClk, |
rstSyncToBusClk, |
fifoSelect, |
fifoDataIn, |
busDataIn, |
busDataOut, |
fifoREn, |
forceEmptySyncToUsbClk, |
forceEmptySyncToBusClk, |
numElementsInFifo |
); |
input [2:0] address; |
input writeEn; |
input strobe_i; |
input busClk; |
input usbClk; |
input rstSyncToBusClk; |
input [7:0] fifoDataIn; |
input [7:0] busDataIn; |
output [7:0] busDataOut; |
output fifoREn; |
output forceEmptySyncToUsbClk; |
output forceEmptySyncToBusClk; |
input [15:0] numElementsInFifo; |
input fifoSelect; |
|
|
wire [2:0] address; |
wire writeEn; |
wire strobe_i; |
wire busClk; |
wire usbClk; |
wire rstSyncToBusClk; |
wire [7:0] fifoDataIn; |
wire [7:0] busDataIn; |
reg [7:0] busDataOut; |
reg fifoREn; |
wire forceEmptySyncToUsbClk; |
wire forceEmptySyncToBusClk; |
wire [15:0] numElementsInFifo; |
wire fifoSelect; |
|
reg forceEmptyReg; |
reg forceEmpty; |
reg forceEmptyToggle; |
reg [2:0] forceEmptyToggleSyncToUsbClk; |
|
//sync write |
always @(posedge busClk) |
begin |
if (writeEn == 1'b1 && fifoSelect == 1'b1 && |
address == `FIFO_CONTROL_REG && strobe_i == 1'b1 && busDataIn[0] == 1'b1) |
forceEmpty <= 1'b1; |
else |
forceEmpty <= 1'b0; |
end |
|
//detect rising edge of 'forceEmpty', and generate toggle signal |
always @(posedge busClk) begin |
if (rstSyncToBusClk == 1'b1) begin |
forceEmptyReg <= 1'b0; |
forceEmptyToggle <= 1'b0; |
end |
else begin |
if (forceEmpty == 1'b1) |
forceEmptyReg <= 1'b1; |
else |
forceEmptyReg <= 1'b0; |
if (forceEmpty == 1'b1 && forceEmptyReg == 1'b0) |
forceEmptyToggle <= ~forceEmptyToggle; |
end |
end |
assign forceEmptySyncToBusClk = (forceEmpty == 1'b1 && forceEmptyReg == 1'b0) ? 1'b1 : 1'b0; |
|
|
// double sync across clock domains to generate 'forceEmptySyncToUsbClk' |
always @(posedge usbClk) begin |
forceEmptyToggleSyncToUsbClk <= {forceEmptyToggleSyncToUsbClk[1:0], forceEmptyToggle}; |
end |
assign forceEmptySyncToUsbClk = forceEmptyToggleSyncToUsbClk[2] ^ forceEmptyToggleSyncToUsbClk[1]; |
|
// async read mux |
always @(address or fifoDataIn or numElementsInFifo) |
begin |
case (address) |
`FIFO_DATA_REG : busDataOut <= fifoDataIn; |
`FIFO_DATA_COUNT_MSB : busDataOut <= numElementsInFifo[15:8]; |
`FIFO_DATA_COUNT_LSB : busDataOut <= numElementsInFifo[7:0]; |
default: busDataOut <= 8'h00; |
endcase |
end |
|
//generate fifo read strobe |
always @(address or writeEn or strobe_i or fifoSelect) begin |
if (address == `FIFO_DATA_REG && writeEn == 1'b0 && |
strobe_i == 1'b1 && fifoSelect == 1'b1) |
fifoREn <= 1'b1; |
else |
fifoREn <= 1'b0; |
end |
|
|
endmodule |
/verilog/usbhostslave/SOFTransmit.v
0,0 → 1,202
|
// File : ../RTL/hostController/softransmit.v |
// Generated : 11/10/06 05:37:21 |
// From : ../RTL/hostController/softransmit.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// softransmit |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_hostcontrol_h.v" |
|
|
module SOFTransmit (SOFEnable, SOFSent, SOFSyncEn, SOFTimerClr, SOFTimer, clk, rst, sendPacketArbiterGnt, sendPacketArbiterReq, sendPacketRdy, sendPacketWEn); |
input SOFEnable; // After host software asserts SOFEnable, must wait TBD time before asserting SOFSyncEn |
input SOFSyncEn; |
input [15:0] SOFTimer; |
input clk; |
input rst; |
input sendPacketArbiterGnt; |
input sendPacketRdy; |
output SOFSent; // single cycle pulse |
output SOFTimerClr; // Single cycle pulse |
output sendPacketArbiterReq; |
output sendPacketWEn; |
|
wire SOFEnable; |
reg SOFSent, next_SOFSent; |
wire SOFSyncEn; |
reg SOFTimerClr, next_SOFTimerClr; |
wire [15:0] SOFTimer; |
wire clk; |
wire rst; |
wire sendPacketArbiterGnt; |
reg sendPacketArbiterReq, next_sendPacketArbiterReq; |
wire sendPacketRdy; |
reg sendPacketWEn, next_sendPacketWEn; |
|
// diagram signals declarations |
reg [7:0]i, next_i; |
|
// BINARY ENCODED state machine: SOFTx |
// State codes definitions: |
`define START_STX 3'b000 |
`define WAIT_SOF_NEAR 3'b001 |
`define WAIT_SP_GNT 3'b010 |
`define WAIT_SOF_NOW 3'b011 |
`define SOF_FIN 3'b100 |
`define DLY_SOF_CHK1 3'b101 |
`define DLY_SOF_CHK2 3'b110 |
|
reg [2:0] CurrState_SOFTx; |
reg [2:0] NextState_SOFTx; |
|
|
//-------------------------------------------------------------------- |
// Machine: SOFTx |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (i or SOFTimer or SOFSyncEn or SOFEnable or sendPacketArbiterGnt or sendPacketRdy or sendPacketArbiterReq or sendPacketWEn or SOFTimerClr or SOFSent or CurrState_SOFTx) |
begin : SOFTx_NextState |
NextState_SOFTx <= CurrState_SOFTx; |
// Set default values for outputs and signals |
next_sendPacketArbiterReq <= sendPacketArbiterReq; |
next_sendPacketWEn <= sendPacketWEn; |
next_SOFTimerClr <= SOFTimerClr; |
next_SOFSent <= SOFSent; |
next_i <= i; |
case (CurrState_SOFTx) |
`START_STX: |
NextState_SOFTx <= `WAIT_SOF_NEAR; |
`WAIT_SOF_NEAR: |
if (SOFTimer >= `SOF_TX_TIME - `SOF_TX_MARGIN || |
(SOFSyncEn == 1'b1 && |
SOFEnable == 1'b1)) |
begin |
NextState_SOFTx <= `WAIT_SP_GNT; |
next_sendPacketArbiterReq <= 1'b1; |
end |
`WAIT_SP_GNT: |
if (sendPacketArbiterGnt == 1'b1 && sendPacketRdy == 1'b1) |
NextState_SOFTx <= `WAIT_SOF_NOW; |
`WAIT_SOF_NOW: |
if (SOFTimer >= `SOF_TX_TIME) |
begin |
NextState_SOFTx <= `SOF_FIN; |
next_sendPacketWEn <= 1'b1; |
next_SOFTimerClr <= 1'b1; |
next_SOFSent <= 1'b1; |
end |
else if (SOFEnable == 1'b0) |
begin |
NextState_SOFTx <= `SOF_FIN; |
next_SOFTimerClr <= 1'b1; |
end |
`SOF_FIN: |
begin |
next_sendPacketWEn <= 1'b0; |
next_SOFTimerClr <= 1'b0; |
next_SOFSent <= 1'b0; |
if (sendPacketRdy == 1'b1) |
begin |
NextState_SOFTx <= `DLY_SOF_CHK1; |
next_i <= 8'h00; |
end |
end |
`DLY_SOF_CHK1: |
begin |
next_i <= i + 1'b1; |
if (i==8'hff) |
begin |
NextState_SOFTx <= `DLY_SOF_CHK2; |
next_sendPacketArbiterReq <= 1'b0; |
next_i <= 8'h00; |
end |
end |
`DLY_SOF_CHK2: |
begin |
next_i <= i + 1'b1; |
if (i==8'hff) |
NextState_SOFTx <= `WAIT_SOF_NEAR; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : SOFTx_CurrentState |
if (rst) |
CurrState_SOFTx <= `START_STX; |
else |
CurrState_SOFTx <= NextState_SOFTx; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : SOFTx_RegOutput |
if (rst) |
begin |
i <= 8'h00; |
SOFSent <= 1'b0; |
SOFTimerClr <= 1'b0; |
sendPacketArbiterReq <= 1'b0; |
sendPacketWEn <= 1'b0; |
end |
else |
begin |
i <= next_i; |
SOFSent <= next_SOFSent; |
SOFTimerClr <= next_SOFTimerClr; |
sendPacketArbiterReq <= next_sendPacketArbiterReq; |
sendPacketWEn <= next_sendPacketWEn; |
end |
end |
|
endmodule |
/verilog/usbhostslave/TxfifoBI.v
0,0 → 1,149
////////////////////////////////////////////////////////////////////// |
//// //// |
//// TxfifoBI.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_wishbonebus_h.v" |
|
module TxfifoBI ( |
address, writeEn, strobe_i, |
busClk, |
usbClk, |
rstSyncToBusClk, |
fifoSelect, |
busDataIn, |
busDataOut, |
fifoWEn, |
forceEmptySyncToUsbClk, |
forceEmptySyncToBusClk, |
numElementsInFifo |
); |
input [2:0] address; |
input writeEn; |
input strobe_i; |
input busClk; |
input usbClk; |
input rstSyncToBusClk; |
input [7:0] busDataIn; |
output [7:0] busDataOut; |
output fifoWEn; |
output forceEmptySyncToUsbClk; |
output forceEmptySyncToBusClk; |
input [15:0] numElementsInFifo; |
input fifoSelect; |
|
|
wire [2:0] address; |
wire writeEn; |
wire strobe_i; |
wire busClk; |
wire usbClk; |
wire rstSyncToBusClk; |
wire [7:0] busDataIn; |
wire [7:0] busDataOut; |
reg fifoWEn; |
wire forceEmptySyncToUsbClk; |
wire forceEmptySyncToBusClk; |
wire [15:0] numElementsInFifo; |
wire fifoSelect; |
|
reg forceEmptyReg; |
reg forceEmpty; |
reg forceEmptyToggle; |
reg [2:0] forceEmptyToggleSyncToUsbClk; |
|
//sync write |
always @(posedge busClk) |
begin |
if (writeEn == 1'b1 && fifoSelect == 1'b1 && |
address == `FIFO_CONTROL_REG && strobe_i == 1'b1 && busDataIn[0] == 1'b1) |
forceEmpty <= 1'b1; |
else |
forceEmpty <= 1'b0; |
end |
|
//detect rising edge of 'forceEmpty', and generate toggle signal |
always @(posedge busClk) begin |
if (rstSyncToBusClk == 1'b1) begin |
forceEmptyReg <= 1'b0; |
forceEmptyToggle <= 1'b0; |
end |
else begin |
if (forceEmpty == 1'b1) |
forceEmptyReg <= 1'b1; |
else |
forceEmptyReg <= 1'b0; |
if (forceEmpty == 1'b1 && forceEmptyReg == 1'b0) |
forceEmptyToggle <= ~forceEmptyToggle; |
end |
end |
assign forceEmptySyncToBusClk = (forceEmpty == 1'b1 && forceEmptyReg == 1'b0) ? 1'b1 : 1'b0; |
|
// double sync across clock domains to generate 'forceEmptySyncToUsbClk' |
always @(posedge usbClk) begin |
forceEmptyToggleSyncToUsbClk <= {forceEmptyToggleSyncToUsbClk[1:0], forceEmptyToggle}; |
end |
assign forceEmptySyncToUsbClk = forceEmptyToggleSyncToUsbClk[2] ^ forceEmptyToggleSyncToUsbClk[1]; |
|
// async read mux |
assign busDataOut = 8'h00; |
//always @(address or fifoFull or numElementsInFifo) |
//begin |
// case (address) |
// `FIFO_STATUS_REG : busDataOut <= {7'b0000000, fifoFull}; |
// `FIFO_DATA_COUNT_MSB : busDataOut <= numElementsInFifo[15:8]; |
// `FIFO_DATA_COUNT_LSB : busDataOut <= numElementsInFifo[7:0]; |
// default: busDataOut <= 8'h00; |
// endcase |
//end |
|
//generate fifo write strobe |
always @(address or writeEn or strobe_i or fifoSelect or busDataIn) begin |
if (address == `FIFO_DATA_REG && writeEn == 1'b1 && |
strobe_i == 1'b1 && fifoSelect == 1'b1) |
fifoWEn <= 1'b1; |
else |
fifoWEn <= 1'b0; |
end |
|
|
endmodule |
/verilog/usbhostslave/SIETransmitter.v
0,0 → 1,714
|
// File : ../RTL/serialInterfaceEngine/SIETransmitter.v |
// Generated : 10/15/06 20:31:22 |
// From : ../RTL/serialInterfaceEngine/SIETransmitter.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// SIETransmitter |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
`include "usbhostslave_constants_h.v" |
|
|
module SIETransmitter (CRC16En, CRC16Result, CRC16UpdateRdy, CRC5En, CRC5Result, CRC5UpdateRdy, CRC5_8Bit, CRCData, JBit, KBit, SIEPortCtrlIn, SIEPortDataIn, SIEPortTxRdy, SIEPortWEn, TxByteOutCtrl, TxByteOutFullSpeedRate, TxByteOut, USBWireCtrl, USBWireData, USBWireFullSpeedRate, USBWireGnt, USBWireRdy, USBWireReq, USBWireWEn, clk, fullSpeedRateIn, processTxByteRdy, processTxByteWEn, rst, rstCRC); |
input [15:0] CRC16Result; |
input CRC16UpdateRdy; |
input [4:0] CRC5Result; |
input CRC5UpdateRdy; |
input [1:0] JBit; |
input [1:0] KBit; |
input [7:0] SIEPortCtrlIn; |
input [7:0] SIEPortDataIn; |
input SIEPortWEn; |
input USBWireGnt; |
input USBWireRdy; |
input clk; |
input fullSpeedRateIn; |
input processTxByteRdy; |
input rst; |
output CRC16En; |
output CRC5En; |
output CRC5_8Bit; |
output [7:0] CRCData; |
output SIEPortTxRdy; |
output [7:0] TxByteOutCtrl; |
output TxByteOutFullSpeedRate; |
output [7:0] TxByteOut; |
output USBWireCtrl; |
output [1:0] USBWireData; |
output USBWireFullSpeedRate; |
output USBWireReq; |
output USBWireWEn; |
output processTxByteWEn; |
output rstCRC; |
|
reg CRC16En, next_CRC16En; |
wire [15:0] CRC16Result; |
wire CRC16UpdateRdy; |
reg CRC5En, next_CRC5En; |
wire [4:0] CRC5Result; |
wire CRC5UpdateRdy; |
reg CRC5_8Bit, next_CRC5_8Bit; |
reg [7:0] CRCData, next_CRCData; |
wire [1:0] JBit; |
wire [1:0] KBit; |
wire [7:0] SIEPortCtrlIn; |
wire [7:0] SIEPortDataIn; |
reg SIEPortTxRdy, next_SIEPortTxRdy; |
wire SIEPortWEn; |
reg [7:0] TxByteOutCtrl, next_TxByteOutCtrl; |
reg TxByteOutFullSpeedRate, next_TxByteOutFullSpeedRate; |
reg [7:0] TxByteOut, next_TxByteOut; |
reg USBWireCtrl, next_USBWireCtrl; |
reg [1:0] USBWireData, next_USBWireData; |
reg USBWireFullSpeedRate, next_USBWireFullSpeedRate; |
wire USBWireGnt; |
wire USBWireRdy; |
reg USBWireReq, next_USBWireReq; |
reg USBWireWEn, next_USBWireWEn; |
wire clk; |
wire fullSpeedRateIn; |
wire processTxByteRdy; |
reg processTxByteWEn, next_processTxByteWEn; |
wire rst; |
reg rstCRC, next_rstCRC; |
|
// diagram signals declarations |
reg [7:0]SIEPortCtrl, next_SIEPortCtrl; |
reg [7:0]SIEPortData, next_SIEPortData; |
reg [2:0]i, next_i; |
reg [15:0]resumeCnt, next_resumeCnt; |
|
// BINARY ENCODED state machine: SIETx |
// State codes definitions: |
`define DIR_CTL_CHK_FIN 6'b000000 |
`define RES_ST_CHK_FIN 6'b000001 |
`define PKT_ST_CHK_PID 6'b000010 |
`define PKT_ST_DATA_DATA_CHK_STOP 6'b000011 |
`define IDLE 6'b000100 |
`define PKT_ST_DATA_DATA_PKT_SENT 6'b000101 |
`define PKT_ST_DATA_PID_PKT_SENT 6'b000110 |
`define PKT_ST_HS_PKT_SENT 6'b000111 |
`define PKT_ST_TKN_CRC_PKT_SENT 6'b001000 |
`define PKT_ST_TKN_PID_PKT_SENT 6'b001001 |
`define PKT_ST_SPCL_PKT_SENT 6'b001010 |
`define PKT_ST_DATA_CRC_PKT_SENT1 6'b001011 |
`define PKT_ST_TKN_BYTE1_PKT_SENT1 6'b001100 |
`define PKT_ST_DATA_CRC_PKT_SENT2 6'b001101 |
`define RES_ST_SND_J_1 6'b001110 |
`define RES_ST_SND_J_2 6'b001111 |
`define RES_ST_SND_SE0_1 6'b010000 |
`define RES_ST_SND_SE0_2 6'b010001 |
`define START_SIETX 6'b010010 |
`define STX_CHK_ST 6'b010011 |
`define STX_WAIT_BYTE 6'b010100 |
`define PKT_ST_TKN_CRC_UPD_CRC 6'b010101 |
`define PKT_ST_TKN_BYTE1_UPD_CRC 6'b010110 |
`define PKT_ST_DATA_DATA_UPD_CRC 6'b010111 |
`define PKT_ST_TKN_CRC_WAIT_BYTE 6'b011000 |
`define PKT_ST_TKN_BYTE1_WAIT_BYTE 6'b011001 |
`define PKT_ST_DATA_DATA_WAIT_BYTE 6'b011010 |
`define DIR_CTL_WAIT_GNT 6'b011011 |
`define RES_ST_WAIT_GNT 6'b011100 |
`define PKT_ST_HS_WAIT_RDY 6'b011101 |
`define DIR_CTL_WAIT_RDY 6'b011110 |
`define PKT_ST_SPCL_WAIT_RDY 6'b011111 |
`define PKT_ST_TKN_CRC_WAIT_RDY 6'b100000 |
`define PKT_ST_TKN_PID_WAIT_RDY 6'b100001 |
`define PKT_ST_DATA_DATA_WAIT_RDY 6'b100010 |
`define RES_ST_WAIT_RDY 6'b100011 |
`define PKT_ST_TKN_BYTE1_WAIT_RDY 6'b100100 |
`define PKT_ST_DATA_PID_WAIT_RDY 6'b100101 |
`define PKT_ST_DATA_CRC_WAIT_RDY1 6'b100110 |
`define PKT_ST_DATA_CRC_WAIT_RDY2 6'b100111 |
`define PKT_ST_WAIT_RDY_PKT 6'b101000 |
`define RES_ST_W_RDY1 6'b101001 |
`define PKT_ST_TKN_CRC_WAIT_CRC_RDY 6'b101010 |
`define PKT_ST_DATA_DATA_WAIT_CRC_RDY 6'b101011 |
`define PKT_ST_TKN_BYTE1_WAIT_CRC_RDY 6'b101100 |
`define TX_LS_EOP_WAIT_GNT1 6'b101101 |
`define TX_LS_EOP_SND_SE0_2 6'b101110 |
`define TX_LS_EOP_SND_SE0_1 6'b101111 |
`define TX_LS_EOP_W_RDY1 6'b110000 |
`define TX_LS_EOP_SND_J 6'b110001 |
`define TX_LS_EOP_W_RDY2 6'b110010 |
`define TX_LS_EOP_W_RDY3 6'b110011 |
`define RES_ST_DELAY 6'b110100 |
`define RES_ST_W_RDY2 6'b110101 |
`define RES_ST_W_RDY3 6'b110110 |
`define RES_ST_W_RDY4 6'b110111 |
`define DIR_CTL_DELAY 6'b111000 |
|
reg [5:0] CurrState_SIETx; |
reg [5:0] NextState_SIETx; |
|
|
//-------------------------------------------------------------------- |
// Machine: SIETx |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (SIEPortDataIn or SIEPortCtrlIn or fullSpeedRateIn or i or SIEPortData or CRC16Result or CRC5Result or KBit or resumeCnt or JBit or SIEPortCtrl or SIEPortWEn or USBWireGnt or USBWireRdy or processTxByteRdy or CRC16UpdateRdy or CRC5UpdateRdy or processTxByteWEn or TxByteOut or TxByteOutCtrl or USBWireData or USBWireCtrl or USBWireReq or USBWireWEn or rstCRC or CRCData or CRC5En or CRC5_8Bit or CRC16En or SIEPortTxRdy or TxByteOutFullSpeedRate or USBWireFullSpeedRate or CurrState_SIETx) |
begin : SIETx_NextState |
NextState_SIETx <= CurrState_SIETx; |
// Set default values for outputs and signals |
next_processTxByteWEn <= processTxByteWEn; |
next_TxByteOut <= TxByteOut; |
next_TxByteOutCtrl <= TxByteOutCtrl; |
next_USBWireData <= USBWireData; |
next_USBWireCtrl <= USBWireCtrl; |
next_USBWireReq <= USBWireReq; |
next_USBWireWEn <= USBWireWEn; |
next_rstCRC <= rstCRC; |
next_CRCData <= CRCData; |
next_CRC5En <= CRC5En; |
next_CRC5_8Bit <= CRC5_8Bit; |
next_CRC16En <= CRC16En; |
next_SIEPortTxRdy <= SIEPortTxRdy; |
next_SIEPortData <= SIEPortData; |
next_SIEPortCtrl <= SIEPortCtrl; |
next_i <= i; |
next_resumeCnt <= resumeCnt; |
next_TxByteOutFullSpeedRate <= TxByteOutFullSpeedRate; |
next_USBWireFullSpeedRate <= USBWireFullSpeedRate; |
case (CurrState_SIETx) |
`IDLE: |
NextState_SIETx <= `STX_WAIT_BYTE; |
`START_SIETX: |
begin |
next_processTxByteWEn <= 1'b0; |
next_TxByteOut <= 8'h00; |
next_TxByteOutCtrl <= 8'h00; |
next_USBWireData <= 2'b00; |
next_USBWireCtrl <= `TRI_STATE; |
next_USBWireReq <= 1'b0; |
next_USBWireWEn <= 1'b0; |
next_rstCRC <= 1'b0; |
next_CRCData <= 8'h00; |
next_CRC5En <= 1'b0; |
next_CRC5_8Bit <= 1'b0; |
next_CRC16En <= 1'b0; |
next_SIEPortTxRdy <= 1'b0; |
next_SIEPortData <= 8'h00; |
next_SIEPortCtrl <= 8'h00; |
next_i <= 3'h0; |
next_resumeCnt <= 16'h0000; |
next_TxByteOutFullSpeedRate <= 1'b0; |
next_USBWireFullSpeedRate <= 1'b0; |
NextState_SIETx <= `STX_WAIT_BYTE; |
end |
`STX_CHK_ST: |
if ((SIEPortCtrl == `TX_PACKET_START) && (SIEPortData[3:0] == `SOF || SIEPortData[3:0] == `PREAMBLE)) |
begin |
NextState_SIETx <= `PKT_ST_WAIT_RDY_PKT; |
next_TxByteOutFullSpeedRate <= 1'b1; |
//SOF and PRE always at full speed |
end |
else if (SIEPortCtrl == `TX_PACKET_START) |
NextState_SIETx <= `PKT_ST_WAIT_RDY_PKT; |
else if (SIEPortCtrl == `TX_LS_KEEP_ALIVE) |
begin |
NextState_SIETx <= `TX_LS_EOP_WAIT_GNT1; |
next_USBWireReq <= 1'b1; |
end |
else if (SIEPortCtrl == `TX_DIRECT_CONTROL) |
begin |
NextState_SIETx <= `DIR_CTL_WAIT_GNT; |
next_USBWireReq <= 1'b1; |
end |
else if (SIEPortCtrl == `TX_IDLE) |
NextState_SIETx <= `IDLE; |
else if (SIEPortCtrl == `TX_RESUME_START) |
begin |
NextState_SIETx <= `RES_ST_WAIT_GNT; |
next_USBWireReq <= 1'b1; |
next_resumeCnt <= 16'h0000; |
next_USBWireFullSpeedRate <= 1'b0; |
//resume always uses low speed timing |
end |
`STX_WAIT_BYTE: |
begin |
next_SIEPortTxRdy <= 1'b1; |
if (SIEPortWEn == 1'b1) |
begin |
NextState_SIETx <= `STX_CHK_ST; |
next_SIEPortData <= SIEPortDataIn; |
next_SIEPortCtrl <= SIEPortCtrlIn; |
next_SIEPortTxRdy <= 1'b0; |
next_TxByteOutFullSpeedRate <= fullSpeedRateIn; |
next_USBWireFullSpeedRate <= fullSpeedRateIn; |
end |
end |
`DIR_CTL_CHK_FIN: |
begin |
next_USBWireWEn <= 1'b0; |
next_i <= i + 1'b1; |
if (i == 3'h7) |
begin |
NextState_SIETx <= `STX_WAIT_BYTE; |
next_USBWireReq <= 1'b0; |
end |
else |
NextState_SIETx <= `DIR_CTL_DELAY; |
end |
`DIR_CTL_WAIT_GNT: |
begin |
next_i <= 3'h0; |
if (USBWireGnt == 1'b1) |
NextState_SIETx <= `DIR_CTL_WAIT_RDY; |
end |
`DIR_CTL_WAIT_RDY: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `DIR_CTL_CHK_FIN; |
next_USBWireData <= SIEPortData[1:0]; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
end |
`DIR_CTL_DELAY: |
NextState_SIETx <= `DIR_CTL_WAIT_RDY; |
`PKT_ST_CHK_PID: |
begin |
next_processTxByteWEn <= 1'b0; |
if (SIEPortData[1:0] == `TOKEN) |
NextState_SIETx <= `PKT_ST_TKN_PID_WAIT_RDY; |
else if (SIEPortData[1:0] == `HANDSHAKE) |
NextState_SIETx <= `PKT_ST_HS_WAIT_RDY; |
else if (SIEPortData[1:0] == `DATA) |
NextState_SIETx <= `PKT_ST_DATA_PID_WAIT_RDY; |
else if (SIEPortData[1:0] == `SPECIAL) |
NextState_SIETx <= `PKT_ST_SPCL_WAIT_RDY; |
end |
`PKT_ST_WAIT_RDY_PKT: |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_CHK_PID; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= `SYNC_BYTE; |
next_TxByteOutCtrl <= `DATA_START; |
end |
`PKT_ST_DATA_CRC_PKT_SENT1: |
begin |
next_processTxByteWEn <= 1'b0; |
NextState_SIETx <= `PKT_ST_DATA_CRC_WAIT_RDY2; |
end |
`PKT_ST_DATA_CRC_PKT_SENT2: |
begin |
next_processTxByteWEn <= 1'b0; |
NextState_SIETx <= `STX_WAIT_BYTE; |
end |
`PKT_ST_DATA_CRC_WAIT_RDY1: |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_DATA_CRC_PKT_SENT1; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= ~CRC16Result[7:0]; |
next_TxByteOutCtrl <= `DATA_STREAM; |
end |
`PKT_ST_DATA_CRC_WAIT_RDY2: |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_DATA_CRC_PKT_SENT2; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= ~CRC16Result[15:8]; |
next_TxByteOutCtrl <= `DATA_STOP; |
end |
`PKT_ST_DATA_DATA_CHK_STOP: |
if (SIEPortCtrl == `TX_PACKET_STOP) |
NextState_SIETx <= `PKT_ST_DATA_CRC_WAIT_RDY1; |
else |
NextState_SIETx <= `PKT_ST_DATA_DATA_WAIT_CRC_RDY; |
`PKT_ST_DATA_DATA_PKT_SENT: |
begin |
next_processTxByteWEn <= 1'b0; |
NextState_SIETx <= `PKT_ST_DATA_DATA_WAIT_BYTE; |
end |
`PKT_ST_DATA_DATA_UPD_CRC: |
begin |
next_CRCData <= SIEPortData; |
next_CRC16En <= 1'b1; |
NextState_SIETx <= `PKT_ST_DATA_DATA_WAIT_RDY; |
end |
`PKT_ST_DATA_DATA_WAIT_BYTE: |
begin |
next_SIEPortTxRdy <= 1'b1; |
if (SIEPortWEn == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_DATA_DATA_CHK_STOP; |
next_SIEPortData <= SIEPortDataIn; |
next_SIEPortCtrl <= SIEPortCtrlIn; |
next_SIEPortTxRdy <= 1'b0; |
end |
end |
`PKT_ST_DATA_DATA_WAIT_RDY: |
begin |
next_CRC16En <= 1'b0; |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_DATA_DATA_PKT_SENT; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= SIEPortData; |
next_TxByteOutCtrl <= `DATA_STREAM; |
end |
end |
`PKT_ST_DATA_DATA_WAIT_CRC_RDY: |
if (CRC16UpdateRdy == 1'b1) |
NextState_SIETx <= `PKT_ST_DATA_DATA_UPD_CRC; |
`PKT_ST_DATA_PID_PKT_SENT: |
begin |
next_processTxByteWEn <= 1'b0; |
next_rstCRC <= 1'b0; |
NextState_SIETx <= `PKT_ST_DATA_DATA_WAIT_BYTE; |
end |
`PKT_ST_DATA_PID_WAIT_RDY: |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_DATA_PID_PKT_SENT; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= SIEPortData; |
next_TxByteOutCtrl <= `DATA_STREAM; |
next_rstCRC <= 1'b1; |
end |
`PKT_ST_HS_PKT_SENT: |
begin |
next_processTxByteWEn <= 1'b0; |
NextState_SIETx <= `STX_WAIT_BYTE; |
end |
`PKT_ST_HS_WAIT_RDY: |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_HS_PKT_SENT; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= SIEPortData; |
next_TxByteOutCtrl <= `DATA_STOP; |
end |
`PKT_ST_SPCL_PKT_SENT: |
begin |
next_processTxByteWEn <= 1'b0; |
NextState_SIETx <= `STX_WAIT_BYTE; |
end |
`PKT_ST_SPCL_WAIT_RDY: |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_SPCL_PKT_SENT; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= SIEPortData; |
next_TxByteOutCtrl <= `DATA_STOP; |
end |
`PKT_ST_TKN_BYTE1_PKT_SENT1: |
begin |
next_processTxByteWEn <= 1'b0; |
NextState_SIETx <= `PKT_ST_TKN_CRC_WAIT_BYTE; |
end |
`PKT_ST_TKN_BYTE1_UPD_CRC: |
begin |
next_CRCData <= SIEPortData; |
next_CRC5_8Bit <= 1'b1; |
next_CRC5En <= 1'b1; |
NextState_SIETx <= `PKT_ST_TKN_BYTE1_WAIT_RDY; |
end |
`PKT_ST_TKN_BYTE1_WAIT_BYTE: |
begin |
next_SIEPortTxRdy <= 1'b1; |
if (SIEPortWEn == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_TKN_BYTE1_WAIT_CRC_RDY; |
next_SIEPortData <= SIEPortDataIn; |
next_SIEPortCtrl <= SIEPortCtrlIn; |
next_SIEPortTxRdy <= 1'b0; |
end |
end |
`PKT_ST_TKN_BYTE1_WAIT_RDY: |
begin |
next_CRC5En <= 1'b0; |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_TKN_BYTE1_PKT_SENT1; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= SIEPortData; |
next_TxByteOutCtrl <= `DATA_STREAM; |
end |
end |
`PKT_ST_TKN_BYTE1_WAIT_CRC_RDY: |
if (CRC5UpdateRdy == 1'b1) |
NextState_SIETx <= `PKT_ST_TKN_BYTE1_UPD_CRC; |
`PKT_ST_TKN_CRC_PKT_SENT: |
begin |
next_processTxByteWEn <= 1'b0; |
NextState_SIETx <= `STX_WAIT_BYTE; |
end |
`PKT_ST_TKN_CRC_UPD_CRC: |
begin |
next_CRCData <= SIEPortData; |
next_CRC5_8Bit <= 1'b0; |
next_CRC5En <= 1'b1; |
NextState_SIETx <= `PKT_ST_TKN_CRC_WAIT_RDY; |
end |
`PKT_ST_TKN_CRC_WAIT_BYTE: |
begin |
next_SIEPortTxRdy <= 1'b1; |
if (SIEPortWEn == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_TKN_CRC_WAIT_CRC_RDY; |
next_SIEPortData <= SIEPortDataIn; |
next_SIEPortCtrl <= SIEPortCtrlIn; |
next_SIEPortTxRdy <= 1'b0; |
end |
end |
`PKT_ST_TKN_CRC_WAIT_RDY: |
begin |
next_CRC5En <= 1'b0; |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_TKN_CRC_PKT_SENT; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= {~CRC5Result, SIEPortData[2:0] }; |
next_TxByteOutCtrl <= `DATA_STOP; |
end |
end |
`PKT_ST_TKN_CRC_WAIT_CRC_RDY: |
if (CRC5UpdateRdy == 1'b1) |
NextState_SIETx <= `PKT_ST_TKN_CRC_UPD_CRC; |
`PKT_ST_TKN_PID_PKT_SENT: |
begin |
next_processTxByteWEn <= 1'b0; |
next_rstCRC <= 1'b0; |
NextState_SIETx <= `PKT_ST_TKN_BYTE1_WAIT_BYTE; |
end |
`PKT_ST_TKN_PID_WAIT_RDY: |
if (processTxByteRdy == 1'b1) |
begin |
NextState_SIETx <= `PKT_ST_TKN_PID_PKT_SENT; |
next_processTxByteWEn <= 1'b1; |
next_TxByteOut <= SIEPortData; |
next_TxByteOutCtrl <= `DATA_STREAM; |
next_rstCRC <= 1'b1; |
end |
`RES_ST_CHK_FIN: |
begin |
next_USBWireWEn <= 1'b0; |
if (resumeCnt == `HOST_TX_RESUME_TIME) |
NextState_SIETx <= `RES_ST_W_RDY1; |
else |
NextState_SIETx <= `RES_ST_DELAY; |
end |
`RES_ST_SND_J_1: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_SIETx <= `RES_ST_W_RDY4; |
end |
`RES_ST_SND_J_2: |
begin |
next_USBWireWEn <= 1'b0; |
next_USBWireReq <= 1'b0; |
NextState_SIETx <= `STX_WAIT_BYTE; |
next_USBWireFullSpeedRate <= fullSpeedRateIn; |
end |
`RES_ST_SND_SE0_1: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_SIETx <= `RES_ST_W_RDY2; |
end |
`RES_ST_SND_SE0_2: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_SIETx <= `RES_ST_W_RDY3; |
end |
`RES_ST_WAIT_GNT: |
if (USBWireGnt == 1'b1) |
NextState_SIETx <= `RES_ST_WAIT_RDY; |
`RES_ST_WAIT_RDY: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `RES_ST_CHK_FIN; |
next_USBWireData <= KBit; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
next_resumeCnt <= resumeCnt + 1'b1; |
end |
`RES_ST_W_RDY1: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `RES_ST_SND_SE0_1; |
next_USBWireData <= `SE0; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
end |
`RES_ST_DELAY: |
NextState_SIETx <= `RES_ST_WAIT_RDY; |
`RES_ST_W_RDY2: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `RES_ST_SND_SE0_2; |
next_USBWireData <= `SE0; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
end |
`RES_ST_W_RDY3: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `RES_ST_SND_J_1; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
end |
`RES_ST_W_RDY4: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `RES_ST_SND_J_2; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `TRI_STATE; |
next_USBWireWEn <= 1'b1; |
end |
`TX_LS_EOP_WAIT_GNT1: |
if (USBWireGnt == 1'b1) |
NextState_SIETx <= `TX_LS_EOP_W_RDY1; |
`TX_LS_EOP_SND_SE0_2: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_SIETx <= `TX_LS_EOP_W_RDY3; |
end |
`TX_LS_EOP_SND_SE0_1: |
begin |
next_USBWireWEn <= 1'b0; |
NextState_SIETx <= `TX_LS_EOP_W_RDY2; |
end |
`TX_LS_EOP_W_RDY1: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `TX_LS_EOP_SND_SE0_1; |
next_USBWireData <= `SE0; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
end |
`TX_LS_EOP_SND_J: |
begin |
next_USBWireWEn <= 1'b0; |
next_USBWireReq <= 1'b0; |
NextState_SIETx <= `STX_WAIT_BYTE; |
end |
`TX_LS_EOP_W_RDY2: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `TX_LS_EOP_SND_SE0_2; |
next_USBWireData <= `SE0; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
end |
`TX_LS_EOP_W_RDY3: |
if (USBWireRdy == 1'b1) |
begin |
NextState_SIETx <= `TX_LS_EOP_SND_J; |
next_USBWireData <= JBit; |
next_USBWireCtrl <= `DRIVE; |
next_USBWireWEn <= 1'b1; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : SIETx_CurrentState |
if (rst) |
CurrState_SIETx <= `START_SIETX; |
else |
CurrState_SIETx <= NextState_SIETx; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : SIETx_RegOutput |
if (rst) |
begin |
SIEPortData <= 8'h00; |
SIEPortCtrl <= 8'h00; |
i <= 3'h0; |
resumeCnt <= 16'h0000; |
processTxByteWEn <= 1'b0; |
TxByteOut <= 8'h00; |
TxByteOutCtrl <= 8'h00; |
USBWireData <= 2'b00; |
USBWireCtrl <= `TRI_STATE; |
USBWireReq <= 1'b0; |
USBWireWEn <= 1'b0; |
rstCRC <= 1'b0; |
CRCData <= 8'h00; |
CRC5En <= 1'b0; |
CRC5_8Bit <= 1'b0; |
CRC16En <= 1'b0; |
SIEPortTxRdy <= 1'b0; |
TxByteOutFullSpeedRate <= 1'b0; |
USBWireFullSpeedRate <= 1'b0; |
end |
else |
begin |
SIEPortData <= next_SIEPortData; |
SIEPortCtrl <= next_SIEPortCtrl; |
i <= next_i; |
resumeCnt <= next_resumeCnt; |
processTxByteWEn <= next_processTxByteWEn; |
TxByteOut <= next_TxByteOut; |
TxByteOutCtrl <= next_TxByteOutCtrl; |
USBWireData <= next_USBWireData; |
USBWireCtrl <= next_USBWireCtrl; |
USBWireReq <= next_USBWireReq; |
USBWireWEn <= next_USBWireWEn; |
rstCRC <= next_rstCRC; |
CRCData <= next_CRCData; |
CRC5En <= next_CRC5En; |
CRC5_8Bit <= next_CRC5_8Bit; |
CRC16En <= next_CRC16En; |
SIEPortTxRdy <= next_SIEPortTxRdy; |
TxByteOutFullSpeedRate <= next_TxByteOutFullSpeedRate; |
USBWireFullSpeedRate <= next_USBWireFullSpeedRate; |
end |
end |
|
endmodule |
/verilog/usbhostslave/fifoMux.v
0,0 → 1,212
////////////////////////////////////////////////////////////////////// |
//// //// |
//// fifoMux.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module fifoMux ( |
currEndP, |
//TxFifo |
TxFifoREn, |
TxFifoEP0REn, |
TxFifoEP1REn, |
TxFifoEP2REn, |
TxFifoEP3REn, |
TxFifoData, |
TxFifoEP0Data, |
TxFifoEP1Data, |
TxFifoEP2Data, |
TxFifoEP3Data, |
TxFifoEmpty, |
TxFifoEP0Empty, |
TxFifoEP1Empty, |
TxFifoEP2Empty, |
TxFifoEP3Empty, |
//RxFifo |
RxFifoWEn, |
RxFifoEP0WEn, |
RxFifoEP1WEn, |
RxFifoEP2WEn, |
RxFifoEP3WEn, |
RxFifoFull, |
RxFifoEP0Full, |
RxFifoEP1Full, |
RxFifoEP2Full, |
RxFifoEP3Full |
); |
|
|
input [3:0] currEndP; |
//TxFifo |
input TxFifoREn; |
output TxFifoEP0REn; |
output TxFifoEP1REn; |
output TxFifoEP2REn; |
output TxFifoEP3REn; |
output [7:0] TxFifoData; |
input [7:0] TxFifoEP0Data; |
input [7:0] TxFifoEP1Data; |
input [7:0] TxFifoEP2Data; |
input [7:0] TxFifoEP3Data; |
output TxFifoEmpty; |
input TxFifoEP0Empty; |
input TxFifoEP1Empty; |
input TxFifoEP2Empty; |
input TxFifoEP3Empty; |
//RxFifo |
input RxFifoWEn; |
output RxFifoEP0WEn; |
output RxFifoEP1WEn; |
output RxFifoEP2WEn; |
output RxFifoEP3WEn; |
output RxFifoFull; |
input RxFifoEP0Full; |
input RxFifoEP1Full; |
input RxFifoEP2Full; |
input RxFifoEP3Full; |
|
wire [3:0] currEndP; |
//TxFifo |
wire TxFifoREn; |
reg TxFifoEP0REn; |
reg TxFifoEP1REn; |
reg TxFifoEP2REn; |
reg TxFifoEP3REn; |
reg [7:0] TxFifoData; |
wire [7:0] TxFifoEP0Data; |
wire [7:0] TxFifoEP1Data; |
wire [7:0] TxFifoEP2Data; |
wire [7:0] TxFifoEP3Data; |
reg TxFifoEmpty; |
wire TxFifoEP0Empty; |
wire TxFifoEP1Empty; |
wire TxFifoEP2Empty; |
wire TxFifoEP3Empty; |
//RxFifo |
wire RxFifoWEn; |
reg RxFifoEP0WEn; |
reg RxFifoEP1WEn; |
reg RxFifoEP2WEn; |
reg RxFifoEP3WEn; |
reg RxFifoFull; |
wire RxFifoEP0Full; |
wire RxFifoEP1Full; |
wire RxFifoEP2Full; |
wire RxFifoEP3Full; |
|
//internal wires and regs |
|
//combinatorially mux TX and RX fifos for end points 0 through 3 |
always @(currEndP or |
TxFifoREn or |
RxFifoWEn or |
TxFifoEP0Data or |
TxFifoEP1Data or |
TxFifoEP2Data or |
TxFifoEP3Data or |
TxFifoEP0Empty or |
TxFifoEP1Empty or |
TxFifoEP2Empty or |
TxFifoEP3Empty or |
RxFifoEP0Full or |
RxFifoEP1Full or |
RxFifoEP2Full or |
RxFifoEP3Full) |
begin |
case (currEndP[1:0]) |
2'b00: begin |
TxFifoEP0REn <= TxFifoREn; |
TxFifoEP1REn <= 1'b0; |
TxFifoEP2REn <= 1'b0; |
TxFifoEP3REn <= 1'b0; |
TxFifoData <= TxFifoEP0Data; |
TxFifoEmpty <= TxFifoEP0Empty; |
RxFifoEP0WEn <= RxFifoWEn; |
RxFifoEP1WEn <= 1'b0; |
RxFifoEP2WEn <= 1'b0; |
RxFifoEP3WEn <= 1'b0; |
RxFifoFull <= RxFifoEP0Full; |
end |
2'b01: begin |
TxFifoEP0REn <= 1'b0; |
TxFifoEP1REn <= TxFifoREn; |
TxFifoEP2REn <= 1'b0; |
TxFifoEP3REn <= 1'b0; |
TxFifoData <= TxFifoEP1Data; |
TxFifoEmpty <= TxFifoEP1Empty; |
RxFifoEP0WEn <= 1'b0; |
RxFifoEP1WEn <= RxFifoWEn; |
RxFifoEP2WEn <= 1'b0; |
RxFifoEP3WEn <= 1'b0; |
RxFifoFull <= RxFifoEP1Full; |
end |
2'b10: begin |
TxFifoEP0REn <= 1'b0; |
TxFifoEP1REn <= 1'b0; |
TxFifoEP2REn <= TxFifoREn; |
TxFifoEP3REn <= 1'b0; |
TxFifoData <= TxFifoEP2Data; |
TxFifoEmpty <= TxFifoEP2Empty; |
RxFifoEP0WEn <= 1'b0; |
RxFifoEP1WEn <= 1'b0; |
RxFifoEP2WEn <= RxFifoWEn; |
RxFifoEP3WEn <= 1'b0; |
RxFifoFull <= RxFifoEP2Full; |
end |
2'b11: begin |
TxFifoEP0REn <= 1'b0; |
TxFifoEP1REn <= 1'b0; |
TxFifoEP2REn <= 1'b0; |
TxFifoEP3REn <= TxFifoREn; |
TxFifoData <= TxFifoEP3Data; |
TxFifoEmpty <= TxFifoEP3Empty; |
RxFifoEP0WEn <= 1'b0; |
RxFifoEP1WEn <= 1'b0; |
RxFifoEP2WEn <= 1'b0; |
RxFifoEP3WEn <= RxFifoWEn; |
RxFifoFull <= RxFifoEP3Full; |
end |
endcase |
end |
|
|
endmodule |
/verilog/usbhostslave/speedCtrlMux.v
0,0 → 1,78
////////////////////////////////////////////////////////////////////// |
//// //// |
//// speedCtrlMux.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module speedCtrlMux (directCtrlRate, directCtrlPol, sendPacketRate, sendPacketPol, sendPacketSel, fullSpeedRate, fullSpeedPol); |
input directCtrlRate; |
input directCtrlPol; |
input sendPacketRate; |
input sendPacketPol; |
input sendPacketSel; |
output fullSpeedRate; |
output fullSpeedPol; |
|
wire directCtrlRate; |
wire directCtrlPol; |
wire sendPacketRate; |
wire sendPacketPol; |
wire sendPacketSel; |
reg fullSpeedRate; |
reg fullSpeedPol; |
|
|
always @(directCtrlRate or directCtrlPol or sendPacketRate or sendPacketPol or sendPacketSel) |
begin |
if (sendPacketSel == 1'b1) |
begin |
fullSpeedRate <= sendPacketRate; |
fullSpeedPol <= sendPacketPol; |
end |
else |
begin |
fullSpeedRate <= directCtrlRate; |
fullSpeedPol <= directCtrlPol; |
end |
end |
|
endmodule |
/verilog/usbhostslave/endpMux.v
0,0 → 1,259
////////////////////////////////////////////////////////////////////// |
//// //// |
//// endpMux.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_slavecontrol_h.v" |
|
module endpMux ( |
clk, |
rst, |
currEndP, |
NAKSent, |
stallSent, |
CRCError, |
bitStuffError, |
RxOverflow, |
RxTimeOut, |
dataSequence, |
ACKRxed, |
transType, |
transTypeNAK, |
endPControlReg, |
clrEPRdy, |
endPMuxErrorsWEn, |
endP0ControlReg, |
endP1ControlReg, |
endP2ControlReg, |
endP3ControlReg, |
endP0StatusReg, |
endP1StatusReg, |
endP2StatusReg, |
endP3StatusReg, |
endP0TransTypeReg, |
endP1TransTypeReg, |
endP2TransTypeReg, |
endP3TransTypeReg, |
endP0NAKTransTypeReg, |
endP1NAKTransTypeReg, |
endP2NAKTransTypeReg, |
endP3NAKTransTypeReg, |
clrEP0Rdy, |
clrEP1Rdy, |
clrEP2Rdy, |
clrEP3Rdy); |
|
|
input clk; |
input rst; |
input [3:0] currEndP; |
input NAKSent; |
input stallSent; |
input CRCError; |
input bitStuffError; |
input RxOverflow; |
input RxTimeOut; |
input dataSequence; |
input ACKRxed; |
input [1:0] transType; |
input [1:0] transTypeNAK; |
output [4:0] endPControlReg; |
input clrEPRdy; |
input endPMuxErrorsWEn; |
input [4:0] endP0ControlReg; |
input [4:0] endP1ControlReg; |
input [4:0] endP2ControlReg; |
input [4:0] endP3ControlReg; |
output [7:0] endP0StatusReg; |
output [7:0] endP1StatusReg; |
output [7:0] endP2StatusReg; |
output [7:0] endP3StatusReg; |
output [1:0] endP0TransTypeReg; |
output [1:0] endP1TransTypeReg; |
output [1:0] endP2TransTypeReg; |
output [1:0] endP3TransTypeReg; |
output [1:0] endP0NAKTransTypeReg; |
output [1:0] endP1NAKTransTypeReg; |
output [1:0] endP2NAKTransTypeReg; |
output [1:0] endP3NAKTransTypeReg; |
output clrEP0Rdy; |
output clrEP1Rdy; |
output clrEP2Rdy; |
output clrEP3Rdy; |
|
wire clk; |
wire rst; |
wire [3:0] currEndP; |
wire NAKSent; |
wire stallSent; |
wire CRCError; |
wire bitStuffError; |
wire RxOverflow; |
wire RxTimeOut; |
wire dataSequence; |
wire ACKRxed; |
wire [1:0] transType; |
wire [1:0] transTypeNAK; |
reg [4:0] endPControlReg; |
wire clrEPRdy; |
wire endPMuxErrorsWEn; |
wire [4:0] endP0ControlReg; |
wire [4:0] endP1ControlReg; |
wire [4:0] endP2ControlReg; |
wire [4:0] endP3ControlReg; |
reg [7:0] endP0StatusReg; |
reg [7:0] endP1StatusReg; |
reg [7:0] endP2StatusReg; |
reg [7:0] endP3StatusReg; |
reg [1:0] endP0TransTypeReg; |
reg [1:0] endP1TransTypeReg; |
reg [1:0] endP2TransTypeReg; |
reg [1:0] endP3TransTypeReg; |
reg [1:0] endP0NAKTransTypeReg; |
reg [1:0] endP1NAKTransTypeReg; |
reg [1:0] endP2NAKTransTypeReg; |
reg [1:0] endP3NAKTransTypeReg; |
reg clrEP0Rdy; |
reg clrEP1Rdy; |
reg clrEP2Rdy; |
reg clrEP3Rdy; |
|
//internal wires and regs |
reg [7:0] endPStatusCombine; |
|
//mux endPControlReg and clrEPRdy |
always @(posedge clk) |
begin |
case (currEndP[1:0]) |
2'b00: begin |
endPControlReg <= endP0ControlReg; |
clrEP0Rdy <= clrEPRdy; |
end |
2'b01: begin |
endPControlReg <= endP1ControlReg; |
clrEP1Rdy <= clrEPRdy; |
end |
2'b10: begin |
endPControlReg <= endP2ControlReg; |
clrEP2Rdy <= clrEPRdy; |
end |
2'b11: begin |
endPControlReg <= endP3ControlReg; |
clrEP3Rdy <= clrEPRdy; |
end |
endcase |
end |
|
//mux endPNAKTransType, endPTransType, endPStatusReg |
//If there was a NAK sent then set the NAKSent bit, and leave the other status reg bits untouched. |
//else update the entire status reg |
always @(posedge clk) |
begin |
if (rst) begin |
endP0NAKTransTypeReg <= 2'b00; |
endP1NAKTransTypeReg <= 2'b00; |
endP2NAKTransTypeReg <= 2'b00; |
endP3NAKTransTypeReg <= 2'b00; |
endP0TransTypeReg <= 2'b00; |
endP1TransTypeReg <= 2'b00; |
endP2TransTypeReg <= 2'b00; |
endP3TransTypeReg <= 2'b00; |
endP0StatusReg <= 4'h0; |
endP1StatusReg <= 4'h0; |
endP2StatusReg <= 4'h0; |
endP3StatusReg <= 4'h0; |
end |
else begin |
if (endPMuxErrorsWEn == 1'b1) begin |
if (NAKSent == 1'b1) begin |
case (currEndP[1:0]) |
2'b00: begin |
endP0NAKTransTypeReg <= transTypeNAK; |
endP0StatusReg <= endP0StatusReg | `NAK_SET_MASK; |
end |
2'b01: begin |
endP1NAKTransTypeReg <= transTypeNAK; |
endP1StatusReg <= endP1StatusReg | `NAK_SET_MASK; |
end |
2'b10: begin |
endP2NAKTransTypeReg <= transTypeNAK; |
endP2StatusReg <= endP2StatusReg | `NAK_SET_MASK; |
end |
2'b11: begin |
endP3NAKTransTypeReg <= transTypeNAK; |
endP3StatusReg <= endP3StatusReg | `NAK_SET_MASK; |
end |
endcase |
end |
else begin |
case (currEndP[1:0]) |
2'b00: begin |
endP0TransTypeReg <= transType; |
endP0StatusReg <= endPStatusCombine; |
end |
2'b01: begin |
endP1TransTypeReg <= transType; |
endP1StatusReg <= endPStatusCombine; |
end |
2'b10: begin |
endP2TransTypeReg <= transType; |
endP2StatusReg <= endPStatusCombine; |
end |
2'b11: begin |
endP3TransTypeReg <= transType; |
endP3StatusReg <= endPStatusCombine; |
end |
endcase |
end |
end |
end |
end |
|
|
//combine status bits into a single word |
always @(dataSequence or ACKRxed or stallSent or RxTimeOut or RxOverflow or bitStuffError or CRCError) |
begin |
endPStatusCombine <= {dataSequence, ACKRxed, stallSent, 1'b0, RxTimeOut, RxOverflow, bitStuffError, CRCError}; |
end |
|
|
endmodule |
/verilog/usbhostslave/usbslave.v
0,0 → 1,474
////////////////////////////////////////////////////////////////////// |
//// //// |
//// usbSlave.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// Top level module |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module usbslave( |
clk_i, |
rst_i, |
address_i, |
data_i, |
data_o, |
we_i, |
strobe_i, |
ack_o, |
usbClk, |
slaveVBusDetIntOut, |
slaveNAKSentIntOut, |
slaveSOFRxedIntOut, |
slaveResetEventIntOut, |
slaveResumeIntOut, |
slaveTransDoneIntOut, |
USBWireDataIn, |
USBWireDataInTick, |
USBWireDataOut, |
USBWireDataOutTick, |
USBWireCtrlOut, |
USBFullSpeed, |
USBDPlusPullup, |
USBDMinusPullup, |
vBusDetect |
); |
parameter EP0_FIFO_DEPTH = 64; |
parameter EP0_FIFO_ADDR_WIDTH = 6; |
parameter EP1_FIFO_DEPTH = 64; |
parameter EP1_FIFO_ADDR_WIDTH = 6; |
parameter EP2_FIFO_DEPTH = 64; |
parameter EP2_FIFO_ADDR_WIDTH = 6; |
parameter EP3_FIFO_DEPTH = 64; |
parameter EP3_FIFO_ADDR_WIDTH = 6; |
|
input clk_i; //Wishbone bus clock. Maximum 5*usbClk=240MHz |
input rst_i; //Wishbone bus sync reset. Synchronous to 'clk_i'. Resets all logic |
input [7:0] address_i; //Wishbone bus address in |
input [7:0] data_i; //Wishbone bus data in |
output [7:0] data_o; //Wishbone bus data out |
input we_i; //Wishbone bus write enable in |
input strobe_i; //Wishbone bus strobe in |
output ack_o; //Wishbone bus acknowledge out |
input usbClk; //usb clock. 48Mhz +/-0.25% |
output slaveSOFRxedIntOut; |
output slaveResetEventIntOut; |
output slaveResumeIntOut; |
output slaveTransDoneIntOut; |
output slaveNAKSentIntOut; |
output slaveVBusDetIntOut; |
input [1:0] USBWireDataIn; |
output [1:0] USBWireDataOut; |
output USBWireDataOutTick; |
output USBWireDataInTick; |
output USBWireCtrlOut; |
output USBFullSpeed; |
output USBDPlusPullup; |
output USBDMinusPullup; |
input vBusDetect; |
|
wire clk_i; |
wire rst_i; |
wire [7:0] address_i; |
wire [7:0] data_i; |
wire [7:0] data_o; |
wire we_i; |
wire strobe_i; |
wire ack_o; |
wire usbClk; |
wire slaveSOFRxedIntOut; |
wire slaveResetEventIntOut; |
wire slaveResumeIntOut; |
wire slaveTransDoneIntOut; |
wire slaveNAKSentIntOut; |
wire slaveVBusDetIntOut; |
wire [1:0] USBWireDataIn; |
wire [1:0] USBWireDataOut; |
wire USBWireDataOutTick; |
wire USBWireDataInTick; |
wire USBWireCtrlOut; |
wire USBFullSpeed; |
wire USBDPlusPullup; |
wire USBDMinusPullup; |
wire vBusDetect; |
|
//internal wiring |
wire slaveControlSel; |
wire hostSlaveMuxSel; |
wire [7:0] dataFromSlaveControl; |
wire [7:0] dataFromHostSlaveMux; |
wire [7:0] RxCtrlOut; |
wire [7:0] RxDataFromSIE; |
wire RxDataOutWEn; |
wire fullSpeedBitRateFromSlave; |
wire fullSpeedPolarityFromSlave; |
wire SIEPortWEnFromSlave; |
wire SIEPortTxRdy; |
wire [7:0] SIEPortDataInFromSlave; |
wire [7:0] SIEPortCtrlInFromSlave; |
wire [1:0] connectState; |
wire resumeDetected; |
wire [7:0] SIEPortDataInToSIE; |
wire SIEPortWEnToSIE; |
wire [7:0] SIEPortCtrlInToSIE; |
wire fullSpeedPolarityToSIE; |
wire fullSpeedBitRateToSIE; |
wire connectSlaveToHost; |
wire noActivityTimeOut; |
wire TxFifoEP0REn; |
wire TxFifoEP1REn; |
wire TxFifoEP2REn; |
wire TxFifoEP3REn; |
wire [7:0] TxFifoEP0Data; |
wire [7:0] TxFifoEP1Data; |
wire [7:0] TxFifoEP2Data; |
wire [7:0] TxFifoEP3Data; |
wire TxFifoEP0Empty; |
wire TxFifoEP1Empty; |
wire TxFifoEP2Empty; |
wire TxFifoEP3Empty; |
wire RxFifoEP0WEn; |
wire RxFifoEP1WEn; |
wire RxFifoEP2WEn; |
wire RxFifoEP3WEn; |
wire RxFifoEP0Full; |
wire RxFifoEP1Full; |
wire RxFifoEP2Full; |
wire RxFifoEP3Full; |
wire [7:0] slaveRxFifoData; |
wire [7:0] dataFromEP0RxFifo; |
wire [7:0] dataFromEP1RxFifo; |
wire [7:0] dataFromEP2RxFifo; |
wire [7:0] dataFromEP3RxFifo; |
wire [7:0] dataFromEP0TxFifo; |
wire [7:0] dataFromEP1TxFifo; |
wire [7:0] dataFromEP2TxFifo; |
wire [7:0] dataFromEP3TxFifo; |
wire slaveEP0RxFifoSel; |
wire slaveEP1RxFifoSel; |
wire slaveEP2RxFifoSel; |
wire slaveEP3RxFifoSel; |
wire slaveEP0TxFifoSel; |
wire slaveEP1TxFifoSel; |
wire slaveEP2TxFifoSel; |
wire slaveEP3TxFifoSel; |
wire rstSyncToBusClk; |
wire rstSyncToUsbClk; |
wire noActivityTimeOutEnableToSIE; |
wire noActivityTimeOutEnableFromHost; |
wire noActivityTimeOutEnableFromSlave; |
|
assign USBFullSpeed = fullSpeedBitRateToSIE; |
assign USBDPlusPullup = (USBFullSpeed & connectSlaveToHost); |
assign USBDMinusPullup = (~USBFullSpeed & connectSlaveToHost); |
|
usbSlaveControl u_usbSlaveControl( |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.usbClk(usbClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.RxByteStatus(RxCtrlOut), |
.RxData(RxDataFromSIE), |
.RxDataValid(RxDataOutWEn), |
.SIERxTimeOut(noActivityTimeOut), |
.SIERxTimeOutEn(noActivityTimeOutEnableFromSlave), |
.RxFifoData(slaveRxFifoData), |
.connectSlaveToHost(connectSlaveToHost), |
.fullSpeedRate(fullSpeedBitRateFromSlave), |
.fullSpeedPol(fullSpeedPolarityFromSlave), |
.SCTxPortEn(SIEPortWEnFromSlave), |
.SCTxPortRdy(SIEPortTxRdy), |
.SCTxPortData(SIEPortDataInFromSlave), |
.SCTxPortCtrl(SIEPortCtrlInFromSlave), |
.vBusDetect(vBusDetect), |
.connectStateIn(connectState), |
.resumeDetectedIn(resumeDetected), |
.busAddress(address_i[4:0]), |
.busDataIn(data_i), |
.busDataOut(dataFromSlaveControl), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.SOFRxedIntOut(slaveSOFRxedIntOut), |
.resetEventIntOut(slaveResetEventIntOut), |
.resumeIntOut(slaveResumeIntOut), |
.transDoneIntOut(slaveTransDoneIntOut), |
.NAKSentIntOut(slaveNAKSentIntOut), |
.vBusDetIntOut(slaveVBusDetIntOut), |
.slaveControlSelect(slaveControlSel), |
.TxFifoEP0REn(TxFifoEP0REn), |
.TxFifoEP1REn(TxFifoEP1REn), |
.TxFifoEP2REn(TxFifoEP2REn), |
.TxFifoEP3REn(TxFifoEP3REn), |
.TxFifoEP0Data(TxFifoEP0Data), |
.TxFifoEP1Data(TxFifoEP1Data), |
.TxFifoEP2Data(TxFifoEP2Data), |
.TxFifoEP3Data(TxFifoEP3Data), |
.TxFifoEP0Empty(TxFifoEP0Empty), |
.TxFifoEP1Empty(TxFifoEP1Empty), |
.TxFifoEP2Empty(TxFifoEP2Empty), |
.TxFifoEP3Empty(TxFifoEP3Empty), |
.RxFifoEP0WEn(RxFifoEP0WEn), |
.RxFifoEP1WEn(RxFifoEP1WEn), |
.RxFifoEP2WEn(RxFifoEP2WEn), |
.RxFifoEP3WEn(RxFifoEP3WEn), |
.RxFifoEP0Full(RxFifoEP0Full), |
.RxFifoEP1Full(RxFifoEP1Full), |
.RxFifoEP2Full(RxFifoEP2Full), |
.RxFifoEP3Full(RxFifoEP3Full) |
); |
|
|
wishBoneBI u_wishBoneBI ( |
.address(address_i), |
.dataIn(data_i), |
.dataOut(data_o), |
.writeEn(we_i), |
.strobe_i(strobe_i), |
.ack_o(ack_o), |
.clk(clk_i), |
.rst(rstSyncToBusClk), |
.hostControlSel(), |
.hostRxFifoSel(), |
.hostTxFifoSel(), |
.slaveControlSel(slaveControlSel), |
.slaveEP0RxFifoSel(slaveEP0RxFifoSel), |
.slaveEP1RxFifoSel(slaveEP1RxFifoSel), |
.slaveEP2RxFifoSel(slaveEP2RxFifoSel), |
.slaveEP3RxFifoSel(slaveEP3RxFifoSel), |
.slaveEP0TxFifoSel(slaveEP0TxFifoSel), |
.slaveEP1TxFifoSel(slaveEP1TxFifoSel), |
.slaveEP2TxFifoSel(slaveEP2TxFifoSel), |
.slaveEP3TxFifoSel(slaveEP3TxFifoSel), |
.hostSlaveMuxSel(hostSlaveMuxSel), |
.dataFromHostControl(8'h00), |
.dataFromHostRxFifo(8'h00), |
.dataFromHostTxFifo(8'h00), |
.dataFromSlaveControl(dataFromSlaveControl), |
.dataFromEP0RxFifo(dataFromEP0RxFifo), |
.dataFromEP1RxFifo(dataFromEP1RxFifo), |
.dataFromEP2RxFifo(dataFromEP2RxFifo), |
.dataFromEP3RxFifo(dataFromEP3RxFifo), |
.dataFromEP0TxFifo(dataFromEP0TxFifo), |
.dataFromEP1TxFifo(dataFromEP1TxFifo), |
.dataFromEP2TxFifo(dataFromEP2TxFifo), |
.dataFromEP3TxFifo(dataFromEP3TxFifo), |
.dataFromHostSlaveMux(dataFromHostSlaveMux) |
); |
|
|
|
assign SIEPortCtrlInToSIE = SIEPortCtrlInFromSlave; |
assign SIEPortDataInToSIE = SIEPortDataInFromSlave; |
assign SIEPortWEnToSIE = SIEPortWEnFromSlave; |
assign fullSpeedPolarityToSIE = fullSpeedPolarityFromSlave; |
assign fullSpeedBitRateToSIE = fullSpeedBitRateFromSlave; |
assign noActivityTimeOutEnableToSIE = noActivityTimeOutEnableFromSlave; |
|
hostSlaveMuxBI u_hostSlaveMuxBI ( |
.dataIn(data_i), |
.dataOut(dataFromHostSlaveMux), |
.address(address_i[0]), |
.writeEn(we_i), |
.strobe_i(strobe_i), |
.usbClk(usbClk), |
.busClk(clk_i), |
.hostSlaveMuxSel(hostSlaveMuxSel), |
.hostMode(), |
.rstFromWire(rst_i), |
.rstSyncToBusClkOut(rstSyncToBusClk), |
.rstSyncToUsbClkOut(rstSyncToUsbClk) |
); |
|
usbSerialInterfaceEngine u_usbSerialInterfaceEngine( |
.clk(usbClk), |
.rst(rstSyncToUsbClk), |
.USBWireDataIn(USBWireDataIn), |
.USBWireDataOut(USBWireDataOut), |
.USBWireDataInTick(USBWireDataInTick), |
.USBWireDataOutTick(USBWireDataOutTick), |
.USBWireCtrlOut(USBWireCtrlOut), |
.connectState(connectState), |
.resumeDetected(resumeDetected), |
.RxCtrlOut(RxCtrlOut), |
.RxDataOutWEn(RxDataOutWEn), |
.RxDataOut(RxDataFromSIE), |
.SIEPortCtrlIn(SIEPortCtrlInToSIE), |
.SIEPortDataIn(SIEPortDataInToSIE), |
.SIEPortTxRdy(SIEPortTxRdy), |
.SIEPortWEn(SIEPortWEnToSIE), |
.fullSpeedPolarity(fullSpeedPolarityToSIE), |
.fullSpeedBitRate(fullSpeedBitRateToSIE), |
.noActivityTimeOut(noActivityTimeOut), |
.noActivityTimeOutEnable(noActivityTimeOutEnableToSIE) |
); |
|
|
|
//---Slave fifos |
|
TxFifo #(EP0_FIFO_DEPTH, EP0_FIFO_ADDR_WIDTH) EP0TxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(TxFifoEP0REn), |
.fifoEmpty(TxFifoEP0Empty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP0TxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP0TxFifo), |
.fifoDataOut(TxFifoEP0Data) ); |
|
TxFifo #(EP1_FIFO_DEPTH, EP1_FIFO_ADDR_WIDTH) EP1TxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(TxFifoEP1REn), |
.fifoEmpty(TxFifoEP1Empty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP1TxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP1TxFifo), |
.fifoDataOut(TxFifoEP1Data) ); |
|
TxFifo #(EP2_FIFO_DEPTH, EP2_FIFO_ADDR_WIDTH) EP2TxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(TxFifoEP2REn), |
.fifoEmpty(TxFifoEP2Empty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP2TxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP2TxFifo), |
.fifoDataOut(TxFifoEP2Data) ); |
|
TxFifo #(EP3_FIFO_DEPTH, EP3_FIFO_ADDR_WIDTH) EP3TxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(TxFifoEP3REn), |
.fifoEmpty(TxFifoEP3Empty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP3TxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP3TxFifo), |
.fifoDataOut(TxFifoEP3Data) ); |
|
RxFifo #(EP0_FIFO_DEPTH, EP0_FIFO_ADDR_WIDTH) EP0RxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(RxFifoEP0WEn), |
.fifoFull(RxFifoEP0Full), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP0RxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP0RxFifo), |
.fifoDataIn(slaveRxFifoData) ); |
|
RxFifo #(EP1_FIFO_DEPTH, EP1_FIFO_ADDR_WIDTH) EP1RxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(RxFifoEP1WEn), |
.fifoFull(RxFifoEP1Full), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP1RxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP1RxFifo), |
.fifoDataIn(slaveRxFifoData) ); |
|
RxFifo #(EP2_FIFO_DEPTH, EP2_FIFO_ADDR_WIDTH) EP2RxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(RxFifoEP2WEn), |
.fifoFull(RxFifoEP2Full), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP2RxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP2RxFifo), |
.fifoDataIn(slaveRxFifoData) ); |
|
RxFifo #(EP3_FIFO_DEPTH, EP3_FIFO_ADDR_WIDTH) EP3RxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(RxFifoEP3WEn), |
.fifoFull(RxFifoEP3Full), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(slaveEP3RxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromEP3RxFifo), |
.fifoDataIn(slaveRxFifoData) ); |
|
|
|
endmodule |
|
|
|
|
|
|
|
/verilog/usbhostslave/HCTxPortArbiter.v
0,0 → 1,239
|
// File : ../RTL/hostController/hctxportarbiter.v |
// Generated : 11/10/06 05:37:22 |
// From : ../RTL/hostController/hctxportarbiter.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// hctxPortArbiter |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module HCTxPortArbiter (HCTxPortCntl, HCTxPortData, HCTxPortWEnable, SOFCntlCntl, SOFCntlData, SOFCntlGnt, SOFCntlReq, SOFCntlWEn, clk, directCntlCntl, directCntlData, directCntlGnt, directCntlReq, directCntlWEn, rst, sendPacketCntl, sendPacketData, sendPacketGnt, sendPacketReq, sendPacketWEn); |
input [7:0] SOFCntlCntl; |
input [7:0] SOFCntlData; |
input SOFCntlReq; |
input SOFCntlWEn; |
input clk; |
input [7:0] directCntlCntl; |
input [7:0] directCntlData; |
input directCntlReq; |
input directCntlWEn; |
input rst; |
input [7:0] sendPacketCntl; |
input [7:0] sendPacketData; |
input sendPacketReq; |
input sendPacketWEn; |
output [7:0] HCTxPortCntl; |
output [7:0] HCTxPortData; |
output HCTxPortWEnable; |
output SOFCntlGnt; |
output directCntlGnt; |
output sendPacketGnt; |
|
reg [7:0] HCTxPortCntl, next_HCTxPortCntl; |
reg [7:0] HCTxPortData, next_HCTxPortData; |
reg HCTxPortWEnable, next_HCTxPortWEnable; |
wire [7:0] SOFCntlCntl; |
wire [7:0] SOFCntlData; |
reg SOFCntlGnt, next_SOFCntlGnt; |
wire SOFCntlReq; |
wire SOFCntlWEn; |
wire clk; |
wire [7:0] directCntlCntl; |
wire [7:0] directCntlData; |
reg directCntlGnt, next_directCntlGnt; |
wire directCntlReq; |
wire directCntlWEn; |
wire rst; |
wire [7:0] sendPacketCntl; |
wire [7:0] sendPacketData; |
reg sendPacketGnt, next_sendPacketGnt; |
wire sendPacketReq; |
wire sendPacketWEn; |
|
|
// Constants |
`define DIRECT_CTRL_MUX 2'b10 |
`define SEND_PACKET_MUX 2'b00 |
`define SOF_CTRL_MUX 2'b01 |
// diagram signals declarations |
reg [1:0]muxCntl, next_muxCntl; |
|
// BINARY ENCODED state machine: HCTxArb |
// State codes definitions: |
`define START_HARB 3'b000 |
`define WAIT_REQ 3'b001 |
`define SEND_SOF 3'b010 |
`define SEND_PACKET 3'b011 |
`define DIRECT_CONTROL 3'b100 |
|
reg [2:0] CurrState_HCTxArb; |
reg [2:0] NextState_HCTxArb; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
// SOFController/directContol/sendPacket mux |
always @(muxCntl or SOFCntlWEn or SOFCntlData or SOFCntlCntl or |
directCntlWEn or directCntlData or directCntlCntl or |
directCntlWEn or directCntlData or directCntlCntl or |
sendPacketWEn or sendPacketData or sendPacketCntl) |
begin |
case (muxCntl) |
`SOF_CTRL_MUX : |
begin |
HCTxPortWEnable <= SOFCntlWEn; |
HCTxPortData <= SOFCntlData; |
HCTxPortCntl <= SOFCntlCntl; |
end |
`DIRECT_CTRL_MUX : |
begin |
HCTxPortWEnable <= directCntlWEn; |
HCTxPortData <= directCntlData; |
HCTxPortCntl <= directCntlCntl; |
end |
`SEND_PACKET_MUX : |
begin |
HCTxPortWEnable <= sendPacketWEn; |
HCTxPortData <= sendPacketData; |
HCTxPortCntl <= sendPacketCntl; |
end |
default : |
begin |
HCTxPortWEnable <= 1'b0; |
HCTxPortData <= 8'h00; |
HCTxPortCntl <= 8'h00; |
end |
endcase |
end |
|
//-------------------------------------------------------------------- |
// Machine: HCTxArb |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (SOFCntlReq or sendPacketReq or directCntlReq or SOFCntlGnt or muxCntl or sendPacketGnt or directCntlGnt or CurrState_HCTxArb) |
begin : HCTxArb_NextState |
NextState_HCTxArb <= CurrState_HCTxArb; |
// Set default values for outputs and signals |
next_SOFCntlGnt <= SOFCntlGnt; |
next_muxCntl <= muxCntl; |
next_sendPacketGnt <= sendPacketGnt; |
next_directCntlGnt <= directCntlGnt; |
case (CurrState_HCTxArb) |
`START_HARB: |
NextState_HCTxArb <= `WAIT_REQ; |
`WAIT_REQ: |
if (SOFCntlReq == 1'b1) |
begin |
NextState_HCTxArb <= `SEND_SOF; |
next_SOFCntlGnt <= 1'b1; |
next_muxCntl <= `SOF_CTRL_MUX; |
end |
else if (sendPacketReq == 1'b1) |
begin |
NextState_HCTxArb <= `SEND_PACKET; |
next_sendPacketGnt <= 1'b1; |
next_muxCntl <= `SEND_PACKET_MUX; |
end |
else if (directCntlReq == 1'b1) |
begin |
NextState_HCTxArb <= `DIRECT_CONTROL; |
next_directCntlGnt <= 1'b1; |
next_muxCntl <= `DIRECT_CTRL_MUX; |
end |
`SEND_SOF: |
if (SOFCntlReq == 1'b0) |
begin |
NextState_HCTxArb <= `WAIT_REQ; |
next_SOFCntlGnt <= 1'b0; |
end |
`SEND_PACKET: |
if (sendPacketReq == 1'b0) |
begin |
NextState_HCTxArb <= `WAIT_REQ; |
next_sendPacketGnt <= 1'b0; |
end |
`DIRECT_CONTROL: |
if (directCntlReq == 1'b0) |
begin |
NextState_HCTxArb <= `WAIT_REQ; |
next_directCntlGnt <= 1'b0; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : HCTxArb_CurrentState |
if (rst) |
CurrState_HCTxArb <= `START_HARB; |
else |
CurrState_HCTxArb <= NextState_HCTxArb; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : HCTxArb_RegOutput |
if (rst) |
begin |
muxCntl <= 2'b00; |
SOFCntlGnt <= 1'b0; |
sendPacketGnt <= 1'b0; |
directCntlGnt <= 1'b0; |
end |
else |
begin |
muxCntl <= next_muxCntl; |
SOFCntlGnt <= next_SOFCntlGnt; |
sendPacketGnt <= next_sendPacketGnt; |
directCntlGnt <= next_directCntlGnt; |
end |
end |
|
endmodule |
/verilog/usbhostslave/writeUSBWireData.v
0,0 → 1,281
////////////////////////////////////////////////////////////////////// |
//// //// |
//// writeUSBWireData.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
`define BUFFER_FULL 3'b100 |
|
module writeUSBWireData ( |
TxBitsIn, |
TxBitsOut, |
TxDataOutTick, |
TxCtrlIn, |
TxCtrlOut, |
USBWireRdy, |
USBWireWEn, |
TxWireActiveDrive, |
fullSpeedRate, |
clk, |
rst |
); |
|
input [1:0] TxBitsIn; |
input TxCtrlIn; |
input USBWireWEn; |
input clk; |
input fullSpeedRate; |
input rst; |
output [1:0] TxBitsOut; |
output TxDataOutTick; |
output TxCtrlOut; |
output USBWireRdy; |
output TxWireActiveDrive; |
|
wire [1:0] TxBitsIn; |
reg [1:0] TxBitsOut; |
reg TxDataOutTick; |
wire TxCtrlIn; |
reg TxCtrlOut; |
reg USBWireRdy; |
wire USBWireWEn; |
wire clk; |
wire fullSpeedRate; |
wire rst; |
reg TxWireActiveDrive; |
|
// local registers |
reg [2:0]buffer0; |
reg [2:0]buffer1; |
reg [2:0]buffer2; |
reg [2:0]buffer3; |
reg [2:0]bufferCnt; |
reg [1:0]bufferInIndex; |
reg [1:0]bufferOutIndex; |
reg decBufferCnt; |
reg [4:0]i; |
reg incBufferCnt; |
reg fullSpeedTick; |
reg lowSpeedTick; |
|
// buffer in state machine state codes: |
`define WAIT_BUFFER_NOT_FULL 2'b00 |
`define WAIT_WRITE_REQ 2'b01 |
`define CLR_INC_BUFFER_CNT 2'b10 |
|
// buffer output state machine state codes: |
`define WAIT_BUFFER_FULL 2'b00 |
`define WAIT_LINE_WRITE 2'b01 |
`define LINE_WRITE 2'b10 |
|
reg [1:0] bufferInStMachCurrState; |
reg [1:0] bufferOutStMachCurrState; |
|
// buffer control |
always @(posedge clk) |
begin |
if (rst == 1'b1) |
begin |
bufferCnt <= 3'b000; |
end |
else |
begin |
if (incBufferCnt == 1'b1 && decBufferCnt == 1'b0) |
bufferCnt <= bufferCnt + 1'b1; |
else if (incBufferCnt == 1'b0 && decBufferCnt == 1'b1) |
bufferCnt <= bufferCnt - 1'b1; |
end |
end |
|
|
//buffer input state machine |
always @(posedge clk) begin |
if (rst == 1'b1) begin |
incBufferCnt <= 1'b0; |
bufferInIndex <= 2'b00; |
buffer0 <= 3'b000; |
buffer1 <= 3'b000; |
buffer2 <= 3'b000; |
buffer3 <= 3'b000; |
USBWireRdy <= 1'b0; |
bufferInStMachCurrState <= `WAIT_BUFFER_NOT_FULL; |
end |
else begin |
case (bufferInStMachCurrState) |
`WAIT_BUFFER_NOT_FULL: |
begin |
if (bufferCnt != `BUFFER_FULL) |
begin |
bufferInStMachCurrState <= `WAIT_WRITE_REQ; |
USBWireRdy <= 1'b1; |
end |
end |
`WAIT_WRITE_REQ: |
begin |
if (USBWireWEn == 1'b1) |
begin |
incBufferCnt <= 1'b1; |
USBWireRdy <= 1'b0; |
bufferInIndex <= bufferInIndex + 1'b1; |
case (bufferInIndex) |
2'b00 : buffer0 <= {TxBitsIn, TxCtrlIn}; |
2'b01 : buffer1 <= {TxBitsIn, TxCtrlIn}; |
2'b10 : buffer2 <= {TxBitsIn, TxCtrlIn}; |
2'b11 : buffer3 <= {TxBitsIn, TxCtrlIn}; |
endcase |
bufferInStMachCurrState <= `CLR_INC_BUFFER_CNT; |
end |
end |
`CLR_INC_BUFFER_CNT: |
begin |
incBufferCnt <= 1'b0; |
if (bufferCnt != (`BUFFER_FULL - 1'b1) ) |
begin |
bufferInStMachCurrState <= `WAIT_WRITE_REQ; |
USBWireRdy <= 1'b1; |
end |
else begin |
bufferInStMachCurrState <= `WAIT_BUFFER_NOT_FULL; |
end |
end |
endcase |
end |
end |
|
//increment counter used to generate USB bit rate |
always @(posedge clk) begin |
if (rst == 1'b1) |
begin |
i <= 5'b00000; |
fullSpeedTick <= 1'b0; |
lowSpeedTick <= 1'b0; |
end |
else |
begin |
i <= i + 1'b1; |
if (i[1:0] == 2'b00) |
fullSpeedTick <= 1'b1; |
else |
fullSpeedTick <= 1'b0; |
if (i == 5'b00000) |
lowSpeedTick <= 1'b1; |
else |
lowSpeedTick <= 1'b0; |
end |
end |
|
//buffer output state machine |
//buffer is constantly emptied at either |
//the full or low speed rate |
//if the buffer is empty, then the output is forced to tri-state |
always @(posedge clk) begin |
if (rst == 1'b1) |
begin |
bufferOutIndex <= 2'b00; |
decBufferCnt <= 1'b0; |
TxBitsOut <= 2'b00; |
TxCtrlOut <= `TRI_STATE; |
TxDataOutTick <= 1'b0; |
bufferOutStMachCurrState <= `WAIT_LINE_WRITE; |
end |
else |
begin |
case (bufferOutStMachCurrState) |
`WAIT_LINE_WRITE: |
begin |
if ((fullSpeedRate == 1'b1 && fullSpeedTick == 1'b1) || (fullSpeedRate == 1'b0 && lowSpeedTick == 1'b1) ) |
begin |
TxDataOutTick <= !TxDataOutTick; |
if (bufferCnt == 0) begin |
TxBitsOut <= 2'b00; |
TxCtrlOut <= `TRI_STATE; |
end |
else begin |
bufferOutStMachCurrState <= `LINE_WRITE; |
decBufferCnt <= 1'b1; |
bufferOutIndex <= bufferOutIndex + 1'b1; |
case (bufferOutIndex) |
2'b00 : |
begin |
TxBitsOut <= buffer0[2:1]; |
TxCtrlOut <= buffer0[0]; |
end |
2'b01 : |
begin |
TxBitsOut <= buffer1[2:1]; |
TxCtrlOut <= buffer1[0]; |
end |
2'b10 : |
begin |
TxBitsOut <= buffer2[2:1]; |
TxCtrlOut <= buffer2[0]; |
end |
2'b11 : |
begin |
TxBitsOut <= buffer3[2:1]; |
TxCtrlOut <= buffer3[0]; |
end |
endcase |
end |
end |
end |
`LINE_WRITE: |
begin |
decBufferCnt <= 1'b0; |
bufferOutStMachCurrState <= `WAIT_LINE_WRITE; |
end |
endcase |
end |
end |
|
// control 'TxWireActiveDrive' |
always @(TxCtrlOut) |
begin |
if (TxCtrlOut == `DRIVE) |
TxWireActiveDrive <= 1'b1; |
else |
TxWireActiveDrive <= 1'b0; |
end |
|
|
endmodule |
/verilog/usbhostslave/sendPacketCheckPreamble.v
0,0 → 1,205
|
// File : ../RTL/hostController/sendpacketcheckpreamble.v |
// Generated : 11/10/06 05:37:21 |
// From : ../RTL/hostController/sendpacketcheckpreamble.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// sendpacketcheckpreamble |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_constants_h.v" |
|
module sendPacketCheckPreamble (clk, preAmbleEnable, rst, sendPacketCPPID, sendPacketCPReady, sendPacketCPWEn, sendPacketPID, sendPacketRdy, sendPacketWEn); |
input clk; |
input preAmbleEnable; |
input rst; |
input [3:0] sendPacketCPPID; |
input sendPacketCPWEn; |
input sendPacketRdy; |
output sendPacketCPReady; |
output [3:0] sendPacketPID; |
output sendPacketWEn; |
|
wire clk; |
wire preAmbleEnable; |
wire rst; |
wire [3:0] sendPacketCPPID; |
reg sendPacketCPReady, next_sendPacketCPReady; |
wire sendPacketCPWEn; |
reg [3:0] sendPacketPID, next_sendPacketPID; |
wire sendPacketRdy; |
reg sendPacketWEn, next_sendPacketWEn; |
|
// BINARY ENCODED state machine: sendPktCP |
// State codes definitions: |
`define SPC_WAIT_EN 4'b0000 |
`define START_SPC 4'b0001 |
`define CHK_PREAM 4'b0010 |
`define PREAM_PKT_SND_PREAM 4'b0011 |
`define PREAM_PKT_WAIT_RDY1 4'b0100 |
`define PREAM_PKT_PREAM_SENT 4'b0101 |
`define PREAM_PKT_SND_PID 4'b0110 |
`define PREAM_PKT_PID_SENT 4'b0111 |
`define REG_PKT_SEND_PID 4'b1000 |
`define REG_PKT_WAIT_RDY1 4'b1001 |
`define REG_PKT_WAIT_RDY 4'b1010 |
`define READY 4'b1011 |
`define PREAM_PKT_WAIT_RDY2 4'b1100 |
`define PREAM_PKT_WAIT_RDY3 4'b1101 |
|
reg [3:0] CurrState_sendPktCP; |
reg [3:0] NextState_sendPktCP; |
|
|
//-------------------------------------------------------------------- |
// Machine: sendPktCP |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (sendPacketCPPID or sendPacketCPWEn or preAmbleEnable or sendPacketRdy or sendPacketCPReady or sendPacketWEn or sendPacketPID or CurrState_sendPktCP) |
begin : sendPktCP_NextState |
NextState_sendPktCP <= CurrState_sendPktCP; |
// Set default values for outputs and signals |
next_sendPacketCPReady <= sendPacketCPReady; |
next_sendPacketWEn <= sendPacketWEn; |
next_sendPacketPID <= sendPacketPID; |
case (CurrState_sendPktCP) |
`SPC_WAIT_EN: |
if (sendPacketCPWEn == 1'b1) |
begin |
NextState_sendPktCP <= `CHK_PREAM; |
next_sendPacketCPReady <= 1'b0; |
end |
`START_SPC: |
NextState_sendPktCP <= `SPC_WAIT_EN; |
`CHK_PREAM: |
if (preAmbleEnable == 1'b1) |
NextState_sendPktCP <= `PREAM_PKT_WAIT_RDY1; |
else |
NextState_sendPktCP <= `REG_PKT_WAIT_RDY1; |
`READY: |
begin |
next_sendPacketCPReady <= 1'b1; |
NextState_sendPktCP <= `SPC_WAIT_EN; |
end |
`PREAM_PKT_SND_PREAM: |
begin |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= `PREAMBLE; |
NextState_sendPktCP <= `PREAM_PKT_PREAM_SENT; |
end |
`PREAM_PKT_WAIT_RDY1: |
if (sendPacketRdy == 1'b1) |
NextState_sendPktCP <= `PREAM_PKT_SND_PREAM; |
`PREAM_PKT_PREAM_SENT: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_sendPktCP <= `PREAM_PKT_WAIT_RDY2; |
end |
`PREAM_PKT_SND_PID: |
begin |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= sendPacketCPPID; |
NextState_sendPktCP <= `PREAM_PKT_PID_SENT; |
end |
`PREAM_PKT_PID_SENT: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_sendPktCP <= `PREAM_PKT_WAIT_RDY3; |
end |
`PREAM_PKT_WAIT_RDY2: |
if (sendPacketRdy == 1'b1) |
NextState_sendPktCP <= `PREAM_PKT_SND_PID; |
`PREAM_PKT_WAIT_RDY3: |
if (sendPacketRdy == 1'b1) |
NextState_sendPktCP <= `READY; |
`REG_PKT_SEND_PID: |
begin |
next_sendPacketWEn <= 1'b1; |
next_sendPacketPID <= sendPacketCPPID; |
NextState_sendPktCP <= `REG_PKT_WAIT_RDY; |
end |
`REG_PKT_WAIT_RDY1: |
if (sendPacketRdy == 1'b1) |
NextState_sendPktCP <= `REG_PKT_SEND_PID; |
`REG_PKT_WAIT_RDY: |
begin |
next_sendPacketWEn <= 1'b0; |
NextState_sendPktCP <= `READY; |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : sendPktCP_CurrentState |
if (rst) |
CurrState_sendPktCP <= `START_SPC; |
else |
CurrState_sendPktCP <= NextState_sendPktCP; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : sendPktCP_RegOutput |
if (rst) |
begin |
sendPacketWEn <= 1'b0; |
sendPacketPID <= 4'b0; |
sendPacketCPReady <= 1'b1; |
end |
else |
begin |
sendPacketWEn <= next_sendPacketWEn; |
sendPacketPID <= next_sendPacketPID; |
sendPacketCPReady <= next_sendPacketCPReady; |
end |
end |
|
endmodule |
/verilog/usbhostslave/usbhost.v
0,0 → 1,314
////////////////////////////////////////////////////////////////////// |
//// //// |
//// usbHost.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// Top level module |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module usbhost( // Uncapitalised name |
clk_i, |
rst_i, |
address_i, |
data_i, |
data_o, |
we_i, |
strobe_i, |
ack_o, |
usbClk, |
hostSOFSentIntOut, |
hostConnEventIntOut, |
hostResumeIntOut, |
hostTransDoneIntOut, |
USBWireDataIn, |
USBWireDataInTick, |
USBWireDataOut, |
USBWireDataOutTick, |
USBWireCtrlOut, |
USBFullSpeed |
); |
parameter HOST_FIFO_DEPTH = 64; //HOST_FIFO_DEPTH = 2^HOST_ADDR_WIDTH |
parameter HOST_FIFO_ADDR_WIDTH = 6; |
|
|
input clk_i; //Wishbone bus clock. Maximum 5*usbClk=240MHz |
input rst_i; //Wishbone bus sync reset. Synchronous to 'clk_i'. Resets all logic |
input [7:0] address_i; //Wishbone bus address in |
input [7:0] data_i; //Wishbone bus data in |
output [7:0] data_o; //Wishbone bus data out |
input we_i; //Wishbone bus write enable in |
input strobe_i; //Wishbone bus strobe in |
output ack_o; //Wishbone bus acknowledge out |
input usbClk; //usb clock. 48Mhz +/-0.25% |
output hostSOFSentIntOut; |
output hostConnEventIntOut; |
output hostResumeIntOut; |
output hostTransDoneIntOut; |
input [1:0] USBWireDataIn; |
output [1:0] USBWireDataOut; |
output USBWireDataOutTick; |
output USBWireDataInTick; |
output USBWireCtrlOut; |
output USBFullSpeed; |
|
wire clk_i; |
wire rst_i; |
wire [7:0] address_i; |
wire [7:0] data_i; |
wire [7:0] data_o; |
wire we_i; |
wire strobe_i; |
wire ack_o; |
wire usbClk; |
wire hostSOFSentIntOut; |
wire hostConnEventIntOut; |
wire hostResumeIntOut; |
wire hostTransDoneIntOut; |
wire [1:0] USBWireDataIn; |
wire [1:0] USBWireDataOut; |
wire USBWireDataOutTick; |
wire USBWireDataInTick; |
wire USBWireCtrlOut; |
wire USBFullSpeed; |
|
//internal wiring |
wire hostControlSel; |
wire slaveControlSel; |
wire hostRxFifoSel; |
wire hostTxFifoSel; |
wire hostSlaveMuxSel; |
wire [7:0] dataFromHostControl; |
wire [7:0] dataFromSlaveControl; |
wire [7:0] dataFromHostRxFifo; |
wire [7:0] dataFromHostTxFifo; |
wire [7:0] dataFromHostSlaveMux; |
wire hostTxFifoRE; |
wire [7:0] hostTxFifoData; |
wire hostTxFifoEmpty; |
wire hostRxFifoWE; |
wire [7:0] hostRxFifoData; |
wire hostRxFifoFull; |
wire [7:0] RxCtrlOut; |
wire [7:0] RxDataFromSIE; |
wire RxDataOutWEn; |
wire fullSpeedBitRateFromHost; |
wire fullSpeedPolarityFromHost; |
wire SIEPortWEnFromHost; |
wire SIEPortTxRdy; |
wire [7:0] SIEPortDataInFromHost; |
wire [7:0] SIEPortCtrlInFromHost; |
wire [1:0] connectState; |
wire resumeDetected; |
wire [7:0] SIEPortDataInToSIE; |
wire SIEPortWEnToSIE; |
wire [7:0] SIEPortCtrlInToSIE; |
wire fullSpeedPolarityToSIE; |
wire fullSpeedBitRateToSIE; |
wire noActivityTimeOut; |
wire rstSyncToBusClk; |
wire rstSyncToUsbClk; |
wire noActivityTimeOutEnableToSIE; |
wire noActivityTimeOutEnableFromHost; |
|
assign USBFullSpeed = fullSpeedBitRateToSIE; |
|
|
usbHostControl u_usbHostControl( |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.usbClk(usbClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.TxFifoRE(hostTxFifoRE), |
.TxFifoData(hostTxFifoData), |
.TxFifoEmpty(hostTxFifoEmpty), |
.RxFifoWE(hostRxFifoWE), |
.RxFifoData(hostRxFifoData), |
.RxFifoFull(hostRxFifoFull), |
.RxByteStatus(RxCtrlOut), |
.RxData(RxDataFromSIE), |
.RxDataValid(RxDataOutWEn), |
.SIERxTimeOut(noActivityTimeOut), |
.SIERxTimeOutEn(noActivityTimeOutEnableFromHost), |
.fullSpeedRate(fullSpeedBitRateFromHost), |
.fullSpeedPol(fullSpeedPolarityFromHost), |
.HCTxPortEn(SIEPortWEnFromHost), |
.HCTxPortRdy(SIEPortTxRdy), |
.HCTxPortData(SIEPortDataInFromHost), |
.HCTxPortCtrl(SIEPortCtrlInFromHost), |
.connectStateIn(connectState), |
.resumeDetectedIn(resumeDetected), |
.busAddress(address_i[3:0]), |
.busDataIn(data_i), |
.busDataOut(dataFromHostControl), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.SOFSentIntOut(hostSOFSentIntOut), |
.connEventIntOut(hostConnEventIntOut), |
.resumeIntOut(hostResumeIntOut), |
.transDoneIntOut(hostTransDoneIntOut), |
.hostControlSelect(hostControlSel) ); |
|
|
wishBoneBI u_wishBoneBI ( |
.address(address_i), |
.dataIn(data_i), |
.dataOut(data_o), |
.writeEn(we_i), |
.strobe_i(strobe_i), |
.ack_o(ack_o), |
.clk(clk_i), |
.rst(rstSyncToBusClk), |
.hostControlSel(hostControlSel), |
.hostRxFifoSel(hostRxFifoSel), |
.hostTxFifoSel(hostTxFifoSel), |
.slaveControlSel(), |
.slaveEP0RxFifoSel(), |
.slaveEP1RxFifoSel(), |
.slaveEP2RxFifoSel(), |
.slaveEP3RxFifoSel(), |
.slaveEP0TxFifoSel(), |
.slaveEP1TxFifoSel(), |
.slaveEP2TxFifoSel(), |
.slaveEP3TxFifoSel(), |
.hostSlaveMuxSel(hostSlaveMuxSel), |
.dataFromHostControl(dataFromHostControl), |
.dataFromHostRxFifo(dataFromHostRxFifo), |
.dataFromHostTxFifo(dataFromHostTxFifo), |
.dataFromSlaveControl(8'h00), |
.dataFromEP0RxFifo(8'h00), |
.dataFromEP1RxFifo(8'h00), |
.dataFromEP2RxFifo(8'h00), |
.dataFromEP3RxFifo(8'h00), |
.dataFromEP0TxFifo(8'h00), |
.dataFromEP1TxFifo(8'h00), |
.dataFromEP2TxFifo(8'h00), |
.dataFromEP3TxFifo(8'h00), |
.dataFromHostSlaveMux(dataFromHostSlaveMux) |
); |
|
|
assign SIEPortCtrlInToSIE = SIEPortCtrlInFromHost; |
assign SIEPortDataInToSIE = SIEPortDataInFromHost; |
assign SIEPortWEnToSIE = SIEPortWEnFromHost; |
assign fullSpeedPolarityToSIE = fullSpeedPolarityFromHost; |
assign fullSpeedBitRateToSIE = fullSpeedBitRateFromHost; |
assign noActivityTimeOutEnableToSIE = noActivityTimeOutEnableFromHost; |
|
hostSlaveMuxBI u_hostSlaveMuxBI ( |
.dataIn(data_i), |
.dataOut(dataFromHostSlaveMux), |
.address(address_i[0]), |
.writeEn(we_i), |
.strobe_i(strobe_i), |
.usbClk(usbClk), |
.busClk(clk_i), |
.hostMode(hostMode), |
.hostSlaveMuxSel(hostSlaveMuxSel), |
.rstFromWire(rst_i), |
.rstSyncToBusClkOut(rstSyncToBusClk), |
.rstSyncToUsbClkOut(rstSyncToUsbClk) |
); |
|
usbSerialInterfaceEngine u_usbSerialInterfaceEngine( |
.clk(usbClk), |
.rst(rstSyncToUsbClk), |
.USBWireDataIn(USBWireDataIn), |
.USBWireDataOut(USBWireDataOut), |
.USBWireDataInTick(USBWireDataInTick), |
.USBWireDataOutTick(USBWireDataOutTick), |
.USBWireCtrlOut(USBWireCtrlOut), |
.connectState(connectState), |
.resumeDetected(resumeDetected), |
.RxCtrlOut(RxCtrlOut), |
.RxDataOutWEn(RxDataOutWEn), |
.RxDataOut(RxDataFromSIE), |
.SIEPortCtrlIn(SIEPortCtrlInToSIE), |
.SIEPortDataIn(SIEPortDataInToSIE), |
.SIEPortTxRdy(SIEPortTxRdy), |
.SIEPortWEn(SIEPortWEnToSIE), |
.fullSpeedPolarity(fullSpeedPolarityToSIE), |
.fullSpeedBitRate(fullSpeedBitRateToSIE), |
.noActivityTimeOut(noActivityTimeOut), |
.noActivityTimeOutEnable(noActivityTimeOutEnableToSIE) |
); |
|
|
|
//---Host fifos |
TxFifo #(HOST_FIFO_DEPTH, HOST_FIFO_ADDR_WIDTH) HostTxFifo ( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoREn(hostTxFifoRE), |
.fifoEmpty(hostTxFifoEmpty), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(hostTxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromHostTxFifo), |
.fifoDataOut(hostTxFifoData) ); |
|
|
RxFifo #(HOST_FIFO_DEPTH, HOST_FIFO_ADDR_WIDTH) HostRxFifo( |
.usbClk(usbClk), |
.busClk(clk_i), |
.rstSyncToBusClk(rstSyncToBusClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.fifoWEn(hostRxFifoWE), |
.fifoFull(hostRxFifoFull), |
.busAddress(address_i[2:0]), |
.busWriteEn(we_i), |
.busStrobe_i(strobe_i), |
.busFifoSelect(hostRxFifoSel), |
.busDataIn(data_i), |
.busDataOut(dataFromHostRxFifo), |
.fifoDataIn(hostRxFifoData) ); |
|
|
endmodule |
|
|
|
|
|
|
|
/verilog/usbhostslave/usbHostControl.v
0,0 → 1,397
////////////////////////////////////////////////////////////////////// |
//// //// |
//// usbHostControl.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module usbHostControl( |
busClk, rstSyncToBusClk, |
usbClk, rstSyncToUsbClk, |
//sendPacket |
TxFifoRE, TxFifoData, TxFifoEmpty, |
//getPacket |
RxFifoWE, RxFifoData, RxFifoFull, |
RxByteStatus, RxData, RxDataValid, |
SIERxTimeOut, SIERxTimeOutEn, |
//speedCtrlMux |
fullSpeedRate, fullSpeedPol, |
//HCTxPortArbiter |
HCTxPortEn, HCTxPortRdy, |
HCTxPortData, HCTxPortCtrl, |
//rxStatusMonitor |
connectStateIn, |
resumeDetectedIn, |
//USBHostControlBI |
busAddress, |
busDataIn, |
busDataOut, |
busWriteEn, |
busStrobe_i, |
SOFSentIntOut, |
connEventIntOut, |
resumeIntOut, |
transDoneIntOut, |
hostControlSelect |
); |
|
input busClk; |
input rstSyncToBusClk; |
input usbClk; |
input rstSyncToUsbClk; |
//sendPacket |
output TxFifoRE; |
input [7:0] TxFifoData; |
input TxFifoEmpty; |
//getPacket |
output RxFifoWE; |
output [7:0] RxFifoData; |
input RxFifoFull; |
input [7:0] RxByteStatus; |
input [7:0] RxData; |
input RxDataValid; |
input SIERxTimeOut; |
output SIERxTimeOutEn; |
//speedCtrlMux |
output fullSpeedRate; |
output fullSpeedPol; |
//HCTxPortArbiter |
output HCTxPortEn; |
input HCTxPortRdy; |
output [7:0] HCTxPortData; |
output [7:0] HCTxPortCtrl; |
//rxStatusMonitor |
input [1:0] connectStateIn; |
input resumeDetectedIn; |
//USBHostControlBI |
input [3:0] busAddress; |
input [7:0] busDataIn; |
output [7:0] busDataOut; |
input busWriteEn; |
input busStrobe_i; |
output SOFSentIntOut; |
output connEventIntOut; |
output resumeIntOut; |
output transDoneIntOut; |
input hostControlSelect; |
|
wire busClk; |
wire rstSyncToBusClk; |
wire usbClk; |
wire rstSyncToUsbClk; |
wire [10:0] frameNum; |
wire SOFSent; |
wire TxFifoRE; |
wire [7:0] TxFifoData; |
wire TxFifoEmpty; |
wire RxFifoWE; |
wire [7:0] RxFifoData; |
wire RxFifoFull; |
wire [7:0] RxByteStatus; |
wire [7:0] RxData; |
wire RxDataValid; |
wire SIERxTimeOut; |
wire SIERxTimeOutEn; |
wire fullSpeedRate; |
wire fullSpeedPol; |
wire HCTxPortEn; |
wire HCTxPortRdy; |
wire [7:0] HCTxPortData; |
wire [7:0] HCTxPortCtrl; |
wire [1:0] connectStateIn; |
wire resumeDetectedIn; |
wire [3:0] busAddress; |
wire [7:0] busDataIn; |
wire [7:0] busDataOut; |
wire busWriteEn; |
wire busStrobe_i; |
wire SOFSentIntOut; |
wire connEventIntOut; |
wire resumeIntOut; |
wire transDoneIntOut; |
wire hostControlSelect; |
|
//internal wiring |
wire SOFTimerClr; |
wire getPacketREn; |
wire getPacketRdy; |
wire HCTxGnt; |
wire HCTxReq; |
wire [3:0] HC_PID; |
wire HC_SP_WEn; |
wire SOFTxGnt; |
wire SOFTxReq; |
wire SOF_SP_WEn; |
wire SOFEnable; |
wire SOFSyncEn; |
wire sendPacketCPReadyIn; |
wire sendPacketCPReadyOut; |
wire [3:0] sendPacketCPPIDIn; |
wire [3:0] sendPacketCPPIDOut; |
wire sendPacketCPWEnIn; |
wire sendPacketCPWEnOut; |
wire [7:0] SOFCntlCntl; |
wire [7:0] SOFCntlData; |
wire SOFCntlGnt; |
wire SOFCntlReq; |
wire SOFCntlWEn; |
wire [7:0] directCntlCntl; |
wire [7:0] directCntlData; |
wire directCntlGnt; |
wire directCntlReq; |
wire directCntlWEn; |
wire [7:0] sendPacketCntl; |
wire [7:0] sendPacketData; |
wire sendPacketGnt; |
wire sendPacketReq; |
wire sendPacketWEn; |
wire [15:0] SOFTimer; |
wire clrTxReq; |
wire transDone; |
wire transReq; |
wire isoEn; |
wire [1:0] transType; |
wire preAmbleEnable; |
wire [1:0] directLineState; |
wire directLineCtrlEn; |
wire [6:0] TxAddr; |
wire [3:0] TxEndP; |
wire [7:0] RxPktStatus; |
wire [3:0] RxPID; |
wire [1:0] connectStateOut; |
wire resumeIntFromRxStatusMon; |
wire connectionEventFromRxStatusMon; |
|
USBHostControlBI u_USBHostControlBI |
(.address(busAddress), |
.dataIn(busDataIn), |
.dataOut(busDataOut), |
.writeEn(busWriteEn), |
.strobe_i(busStrobe_i), |
.busClk(busClk), |
.rstSyncToBusClk(rstSyncToBusClk), |
.usbClk(usbClk), |
.rstSyncToUsbClk(rstSyncToUsbClk), |
.SOFSentIntOut(SOFSentIntOut), |
.connEventIntOut(connEventIntOut), |
.resumeIntOut(resumeIntOut), |
.transDoneIntOut(transDoneIntOut), |
.TxTransTypeReg(transType), |
.TxSOFEnableReg(SOFEnable), |
.TxAddrReg(TxAddr), |
.TxEndPReg(TxEndP), |
.frameNumIn(frameNum), |
.RxPktStatusIn(RxPktStatus), |
.RxPIDIn(RxPID), |
.connectStateIn(connectStateOut), |
.SOFSentIn(SOFSent), |
.connEventIn(connectionEventFromRxStatusMon), |
.resumeIntIn(resumeIntFromRxStatusMon), |
.transDoneIn(transDone), |
.hostControlSelect(hostControlSelect), |
.clrTransReq(clrTxReq), |
.preambleEn(preAmbleEnable), |
.SOFSync(SOFSyncEn), |
.TxLineState(directLineState), |
.LineDirectControlEn(directLineCtrlEn), |
.fullSpeedPol(fullSpeedPol), |
.fullSpeedRate(fullSpeedRate), |
.transReq(transReq), |
.isoEn(isoEn), |
.SOFTimer(SOFTimer) |
); |
|
|
hostcontroller u_hostController |
(.RXStatus(RxPktStatus), |
.clearTXReq(clrTxReq), |
.clk(usbClk), |
.getPacketREn(getPacketREn), |
.getPacketRdy(getPacketRdy), |
.rst(rstSyncToUsbClk), |
.sendPacketArbiterGnt(HCTxGnt), |
.sendPacketArbiterReq(HCTxReq), |
.sendPacketPID(HC_PID), |
.sendPacketRdy(sendPacketCPReadyOut), |
.sendPacketWEn(HC_SP_WEn), |
.transDone(transDone), |
.transReq(transReq), |
.transType(transType), |
.isoEn(isoEn) ); |
|
SOFController u_SOFController |
(.HCTxPortCntl(SOFCntlCntl), |
.HCTxPortData(SOFCntlData), |
.HCTxPortGnt(SOFCntlGnt), |
.HCTxPortRdy(HCTxPortRdy), |
.HCTxPortReq(SOFCntlReq), |
.HCTxPortWEn(SOFCntlWEn), |
.SOFEnable(SOFEnable), |
.SOFTimerClr(SOFTimerClr), |
.SOFTimer(SOFTimer), |
.clk(usbClk), |
.rst(rstSyncToUsbClk) ); |
|
SOFTransmit u_SOFTransmit |
(.SOFEnable(SOFEnable), |
.SOFSent(SOFSent), |
.SOFSyncEn(SOFSyncEn), |
.SOFTimerClr(SOFTimerClr), |
.SOFTimer(SOFTimer), |
.clk(usbClk), |
.rst(rstSyncToUsbClk), |
.sendPacketArbiterGnt(SOFTxGnt), |
.sendPacketArbiterReq(SOFTxReq), |
.sendPacketRdy(sendPacketCPReadyOut), |
.sendPacketWEn(SOF_SP_WEn) ); |
|
|
sendPacketArbiter u_sendPacketArbiter |
(.HCTxGnt(HCTxGnt), |
.HCTxReq(HCTxReq), |
.HC_PID(HC_PID), |
.HC_SP_WEn(HC_SP_WEn), |
.SOFTxGnt(SOFTxGnt), |
.SOFTxReq(SOFTxReq), |
.SOF_SP_WEn(SOF_SP_WEn), |
.clk(usbClk), |
.rst(rstSyncToUsbClk), |
.sendPacketPID(sendPacketCPPIDIn), |
.sendPacketWEnable(sendPacketCPWEnIn) ); |
|
sendPacketCheckPreamble u_sendPacketCheckPreamble |
(.sendPacketCPPID(sendPacketCPPIDIn), |
.clk(usbClk), |
.preAmbleEnable(preAmbleEnable), |
.rst(rstSyncToUsbClk), |
.sendPacketCPReady(sendPacketCPReadyOut), |
.sendPacketCPWEn(sendPacketCPWEnIn), |
.sendPacketPID(sendPacketCPPIDOut), |
.sendPacketRdy(sendPacketCPReadyIn), |
.sendPacketWEn(sendPacketCPWEnOut) ); |
|
sendPacket u_sendPacket |
(.HCTxPortCntl(sendPacketCntl), |
.HCTxPortData(sendPacketData), |
.HCTxPortGnt(sendPacketGnt), |
.HCTxPortRdy(HCTxPortRdy), |
.HCTxPortReq(sendPacketReq), |
.HCTxPortWEn(sendPacketWEn), |
.PID(sendPacketCPPIDOut), |
.TxAddr(TxAddr), |
.TxEndP(TxEndP), |
.clk(usbClk), |
.fifoData(TxFifoData), |
.fifoEmpty(TxFifoEmpty), |
.fifoReadEn(TxFifoRE), |
.frameNum(frameNum), |
.rst(rstSyncToUsbClk), |
.sendPacketRdy(sendPacketCPReadyIn), |
.sendPacketWEn(sendPacketCPWEnOut), |
.fullSpeedPolarity(fullSpeedPol) ); |
|
directControl u_directControl |
(.HCTxPortCntl(directCntlCntl), |
.HCTxPortData(directCntlData), |
.HCTxPortGnt(directCntlGnt), |
.HCTxPortRdy(HCTxPortRdy), |
.HCTxPortReq(directCntlReq), |
.HCTxPortWEn(directCntlWEn), |
.clk(usbClk), |
.directControlEn(directLineCtrlEn), |
.directControlLineState(directLineState), |
.rst(rstSyncToUsbClk) ); |
|
HCTxPortArbiter u_HCTxPortArbiter |
(.HCTxPortCntl(HCTxPortCtrl), |
.HCTxPortData(HCTxPortData), |
.HCTxPortWEnable(HCTxPortEn), |
.SOFCntlCntl(SOFCntlCntl), |
.SOFCntlData(SOFCntlData), |
.SOFCntlGnt(SOFCntlGnt), |
.SOFCntlReq(SOFCntlReq), |
.SOFCntlWEn(SOFCntlWEn), |
.clk(usbClk), |
.directCntlCntl(directCntlCntl), |
.directCntlData(directCntlData), |
.directCntlGnt(directCntlGnt), |
.directCntlReq(directCntlReq), |
.directCntlWEn(directCntlWEn), |
.rst(rstSyncToUsbClk), |
.sendPacketCntl(sendPacketCntl), |
.sendPacketData(sendPacketData), |
.sendPacketGnt(sendPacketGnt), |
.sendPacketReq(sendPacketReq), |
.sendPacketWEn(sendPacketWEn) ); |
|
getPacket u_getPacket |
(.RXDataIn(RxData), |
.RXDataValid(RxDataValid), |
.RXFifoData(RxFifoData), |
.RXFifoFull(RxFifoFull), |
.RXFifoWEn(RxFifoWE), |
.RXPacketRdy(getPacketRdy), |
.RXPktStatus(RxPktStatus), |
.RXStreamStatusIn(RxByteStatus), |
.RxPID(RxPID), |
.SIERxTimeOut(SIERxTimeOut), |
.SIERxTimeOutEn(SIERxTimeOutEn), |
.clk(usbClk), |
.getPacketEn(getPacketREn), |
.rst(rstSyncToUsbClk) ); |
|
rxStatusMonitor u_rxStatusMonitor |
(.connectStateIn(connectStateIn), |
.connectStateOut(connectStateOut), |
.resumeDetectedIn(resumeDetectedIn), |
.connectionEventOut(connectionEventFromRxStatusMon), |
.resumeIntOut(resumeIntFromRxStatusMon), |
.clk(usbClk), |
.rst(rstSyncToUsbClk) ); |
|
endmodule |
|
|
|
|
|
|
|
/verilog/usbhostslave/README
0,0 → 1,8
USB 1.1 host/slave RTL |
|
http://opencores.org/project,usbhostslave |
|
This RTL contains both usbhost and slave cores. See the top-level files, usbhost.v, usbslave.v and usbhostslave.v for the desired configuration of the core. |
|
Include files are prefixed with usbhostslave_ in the include/ directory. |
|
/verilog/usbhostslave/wishBoneBI.v
0,0 → 1,245
////////////////////////////////////////////////////////////////////// |
//// //// |
//// wishBoneBI.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_wishbonebus_h.v" |
|
|
module wishBoneBI ( |
address, dataIn, dataOut, writeEn, |
strobe_i, |
ack_o, |
clk, rst, |
hostControlSel, |
hostRxFifoSel, hostTxFifoSel, |
slaveControlSel, |
slaveEP0RxFifoSel, slaveEP1RxFifoSel, slaveEP2RxFifoSel, slaveEP3RxFifoSel, |
slaveEP0TxFifoSel, slaveEP1TxFifoSel, slaveEP2TxFifoSel, slaveEP3TxFifoSel, |
hostSlaveMuxSel, |
dataFromHostControl, |
dataFromHostRxFifo, |
dataFromHostTxFifo, |
dataFromSlaveControl, |
dataFromEP0RxFifo, dataFromEP1RxFifo, dataFromEP2RxFifo, dataFromEP3RxFifo, |
dataFromEP0TxFifo, dataFromEP1TxFifo, dataFromEP2TxFifo, dataFromEP3TxFifo, |
dataFromHostSlaveMux |
); |
input clk; |
input rst; |
input [7:0] address; |
input [7:0] dataIn; |
output [7:0] dataOut; |
input strobe_i; |
output ack_o; |
input writeEn; |
output hostControlSel; |
output hostRxFifoSel; |
output hostTxFifoSel; |
output slaveControlSel; |
output slaveEP0RxFifoSel, slaveEP1RxFifoSel, slaveEP2RxFifoSel, slaveEP3RxFifoSel; |
output slaveEP0TxFifoSel, slaveEP1TxFifoSel, slaveEP2TxFifoSel, slaveEP3TxFifoSel; |
output hostSlaveMuxSel; |
input [7:0] dataFromHostControl; |
input [7:0] dataFromHostRxFifo; |
input [7:0] dataFromHostTxFifo; |
input [7:0] dataFromSlaveControl; |
input [7:0] dataFromEP0RxFifo, dataFromEP1RxFifo, dataFromEP2RxFifo, dataFromEP3RxFifo; |
input [7:0] dataFromEP0TxFifo, dataFromEP1TxFifo, dataFromEP2TxFifo, dataFromEP3TxFifo; |
input [7:0] dataFromHostSlaveMux; |
|
|
wire clk; |
wire rst; |
wire [7:0] address; |
wire [7:0] dataIn; |
reg [7:0] dataOut; |
wire writeEn; |
wire strobe_i; |
reg ack_o; |
reg hostControlSel; |
reg hostRxFifoSel; |
reg hostTxFifoSel; |
reg slaveControlSel; |
reg slaveEP0RxFifoSel, slaveEP1RxFifoSel, slaveEP2RxFifoSel, slaveEP3RxFifoSel; |
reg slaveEP0TxFifoSel, slaveEP1TxFifoSel, slaveEP2TxFifoSel, slaveEP3TxFifoSel; |
reg hostSlaveMuxSel; |
wire [7:0] dataFromHostControl; |
wire [7:0] dataFromHostRxFifo; |
wire [7:0] dataFromHostTxFifo; |
wire [7:0] dataFromSlaveControl; |
wire [7:0] dataFromEP0RxFifo, dataFromEP1RxFifo, dataFromEP2RxFifo, dataFromEP3RxFifo; |
wire [7:0] dataFromEP0TxFifo, dataFromEP1TxFifo, dataFromEP2TxFifo, dataFromEP3TxFifo; |
wire [7:0] dataFromHostSlaveMux; |
|
//internal wires and regs |
reg ack_delayed; |
reg ack_immediate; |
|
//address decode and data mux |
always @(address or |
dataFromHostControl or |
dataFromHostRxFifo or |
dataFromHostTxFifo or |
dataFromSlaveControl or |
dataFromEP0RxFifo or |
dataFromEP1RxFifo or |
dataFromEP2RxFifo or |
dataFromEP3RxFifo or |
dataFromHostSlaveMux or |
dataFromEP0TxFifo or |
dataFromEP1TxFifo or |
dataFromEP2TxFifo or |
dataFromEP3TxFifo) |
begin |
hostControlSel <= 1'b0; |
hostRxFifoSel <= 1'b0; |
hostTxFifoSel <= 1'b0; |
slaveControlSel <= 1'b0; |
slaveEP0RxFifoSel <= 1'b0; |
slaveEP0TxFifoSel <= 1'b0; |
slaveEP1RxFifoSel <= 1'b0; |
slaveEP1TxFifoSel <= 1'b0; |
slaveEP2RxFifoSel <= 1'b0; |
slaveEP2TxFifoSel <= 1'b0; |
slaveEP3RxFifoSel <= 1'b0; |
slaveEP3TxFifoSel <= 1'b0; |
hostSlaveMuxSel <= 1'b0; |
case (address & `ADDRESS_DECODE_MASK) |
`HCREG_BASE : begin |
hostControlSel <= 1'b1; |
dataOut <= dataFromHostControl; |
end |
`HCREG_BASE_PLUS_0X10 : begin |
hostControlSel <= 1'b1; |
dataOut <= dataFromHostControl; |
end |
`HOST_RX_FIFO_BASE : begin |
hostRxFifoSel <= 1'b1; |
dataOut <= dataFromHostRxFifo; |
end |
`HOST_TX_FIFO_BASE : begin |
hostTxFifoSel <= 1'b1; |
dataOut <= dataFromHostTxFifo; |
end |
`SCREG_BASE : begin |
slaveControlSel <= 1'b1; |
dataOut <= dataFromSlaveControl; |
end |
`SCREG_BASE_PLUS_0X10 : begin |
slaveControlSel <= 1'b1; |
dataOut <= dataFromSlaveControl; |
end |
`EP0_RX_FIFO_BASE : begin |
slaveEP0RxFifoSel <= 1'b1; |
dataOut <= dataFromEP0RxFifo; |
end |
`EP0_TX_FIFO_BASE : begin |
slaveEP0TxFifoSel <= 1'b1; |
dataOut <= dataFromEP0TxFifo; |
end |
`EP1_RX_FIFO_BASE : begin |
slaveEP1RxFifoSel <= 1'b1; |
dataOut <= dataFromEP1RxFifo; |
end |
`EP1_TX_FIFO_BASE : begin |
slaveEP1TxFifoSel <= 1'b1; |
dataOut <= dataFromEP1TxFifo; |
end |
`EP2_RX_FIFO_BASE : begin |
slaveEP2RxFifoSel <= 1'b1; |
dataOut <= dataFromEP2RxFifo; |
end |
`EP2_TX_FIFO_BASE : begin |
slaveEP2TxFifoSel <= 1'b1; |
dataOut <= dataFromEP2TxFifo; |
end |
`EP3_RX_FIFO_BASE : begin |
slaveEP3RxFifoSel <= 1'b1; |
dataOut <= dataFromEP3RxFifo; |
end |
`EP3_TX_FIFO_BASE : begin |
slaveEP3TxFifoSel <= 1'b1; |
dataOut <= dataFromEP3TxFifo; |
end |
`HOST_SLAVE_CONTROL_BASE : begin |
hostSlaveMuxSel <= 1'b1; |
dataOut <= dataFromHostSlaveMux; |
end |
default: |
dataOut <= 8'h00; |
endcase |
end |
|
//delayed ack |
always @(posedge clk) begin |
ack_delayed <= strobe_i; |
end |
|
//immediate ack |
always @(strobe_i) begin |
ack_immediate <= strobe_i; |
end |
|
//select between immediate and delayed ack |
always @(writeEn or address or ack_delayed or ack_immediate) begin |
if (writeEn == 1'b0 && |
(address == `HOST_RX_FIFO_BASE + `FIFO_DATA_REG || |
address == `HOST_TX_FIFO_BASE + `FIFO_DATA_REG || |
address == `EP0_RX_FIFO_BASE + `FIFO_DATA_REG || |
address == `EP0_TX_FIFO_BASE + `FIFO_DATA_REG || |
address == `EP1_RX_FIFO_BASE + `FIFO_DATA_REG || |
address == `EP1_TX_FIFO_BASE + `FIFO_DATA_REG || |
address == `EP2_RX_FIFO_BASE + `FIFO_DATA_REG || |
address == `EP2_TX_FIFO_BASE + `FIFO_DATA_REG || |
address == `EP3_RX_FIFO_BASE + `FIFO_DATA_REG || |
address == `EP3_TX_FIFO_BASE + `FIFO_DATA_REG) ) |
begin |
ack_o <= ack_delayed & ack_immediate; |
end |
else |
begin |
ack_o <= ack_immediate; |
end |
end |
|
endmodule |
/verilog/usbhostslave/lineControlUpdate.v
0,0 → 1,75
////////////////////////////////////////////////////////////////////// |
//// //// |
//// lineControlUpdate.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
module lineControlUpdate(fullSpeedPolarity, fullSpeedBitRate, JBit, KBit); |
input fullSpeedPolarity; |
input fullSpeedBitRate; |
output [1:0] JBit; |
output [1:0] KBit; |
|
wire fullSpeedPolarity; |
wire fullSpeedBitRate; |
reg [1:0] JBit; |
reg [1:0] KBit; |
|
|
|
always @(fullSpeedPolarity) |
begin |
if (fullSpeedPolarity == 1'b1) |
begin |
JBit = `ONE_ZERO; |
KBit = `ZERO_ONE; |
end |
else |
begin |
JBit = `ZERO_ONE; |
KBit = `ONE_ZERO; |
end |
end |
|
|
endmodule |
/verilog/usbhostslave/RxFifo.v
0,0 → 1,134
////////////////////////////////////////////////////////////////////// |
//// //// |
//// RxFifo.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// parameterized RxFifo wrapper. Min depth = 2, Max depth = 65536 |
//// fifo read access via bus interface, fifo write access is direct |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module RxFifo( |
busClk, |
usbClk, |
rstSyncToBusClk, |
rstSyncToUsbClk, |
fifoWEn, |
fifoFull, |
busAddress, |
busWriteEn, |
busStrobe_i, |
busFifoSelect, |
busDataIn, |
busDataOut, |
fifoDataIn ); |
//FIFO_DEPTH = ADDR_WIDTH^2 |
parameter FIFO_DEPTH = 64; |
parameter ADDR_WIDTH = 6; |
|
input busClk; |
input usbClk; |
input rstSyncToBusClk; |
input rstSyncToUsbClk; |
input fifoWEn; |
output fifoFull; |
input [2:0] busAddress; |
input busWriteEn; |
input busStrobe_i; |
input busFifoSelect; |
input [7:0] busDataIn; |
output [7:0] busDataOut; |
input [7:0] fifoDataIn; |
|
wire busClk; |
wire usbClk; |
wire rstSyncToBusClk; |
wire rstSyncToUsbClk; |
wire fifoWEn; |
wire fifoFull; |
wire [2:0] busAddress; |
wire busWriteEn; |
wire busStrobe_i; |
wire busFifoSelect; |
wire [7:0] busDataIn; |
wire [7:0] busDataOut; |
wire [7:0] fifoDataIn; |
|
//internal wires and regs |
wire [7:0] dataFromFifoToBus; |
wire fifoREn; |
wire forceEmptySyncToBusClk; |
wire forceEmptySyncToUsbClk; |
wire [15:0] numElementsInFifo; |
wire fifoEmpty; //not used |
|
fifoRTL #(8, FIFO_DEPTH, ADDR_WIDTH) u_fifo( |
.wrClk(usbClk), |
.rdClk(busClk), |
.rstSyncToWrClk(rstSyncToUsbClk), |
.rstSyncToRdClk(rstSyncToBusClk), |
.dataIn(fifoDataIn), |
.dataOut(dataFromFifoToBus), |
.fifoWEn(fifoWEn), |
.fifoREn(fifoREn), |
.fifoFull(fifoFull), |
.fifoEmpty(fifoEmpty), |
.forceEmptySyncToWrClk(forceEmptySyncToUsbClk), |
.forceEmptySyncToRdClk(forceEmptySyncToBusClk), |
.numElementsInFifo(numElementsInFifo) ); |
|
RxfifoBI u_RxfifoBI( |
.address(busAddress), |
.writeEn(busWriteEn), |
.strobe_i(busStrobe_i), |
.busClk(busClk), |
.usbClk(usbClk), |
.rstSyncToBusClk(rstSyncToBusClk), |
.fifoSelect(busFifoSelect), |
.fifoDataIn(dataFromFifoToBus), |
.busDataIn(busDataIn), |
.busDataOut(busDataOut), |
.fifoREn(fifoREn), |
.forceEmptySyncToBusClk(forceEmptySyncToBusClk), |
.forceEmptySyncToUsbClk(forceEmptySyncToUsbClk), |
.numElementsInFifo(numElementsInFifo) |
); |
|
endmodule |
/verilog/usbhostslave/SCTxPortArbiter.v
0,0 → 1,202
|
// File : ../RTL/slaveController/sctxportarbiter.v |
// Generated : 11/10/06 05:37:24 |
// From : ../RTL/slaveController/sctxportarbiter.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// SCTxPortArbiter |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module SCTxPortArbiter (SCTxPortCntl, SCTxPortData, SCTxPortRdyIn, SCTxPortRdyOut, SCTxPortWEnable, clk, directCntlCntl, directCntlData, directCntlGnt, directCntlReq, directCntlWEn, rst, sendPacketCntl, sendPacketData, sendPacketGnt, sendPacketReq, sendPacketWEn); |
input SCTxPortRdyIn; |
input clk; |
input [7:0] directCntlCntl; |
input [7:0] directCntlData; |
input directCntlReq; |
input directCntlWEn; |
input rst; |
input [7:0] sendPacketCntl; |
input [7:0] sendPacketData; |
input sendPacketReq; |
input sendPacketWEn; |
output [7:0] SCTxPortCntl; |
output [7:0] SCTxPortData; |
output SCTxPortRdyOut; |
output SCTxPortWEnable; |
output directCntlGnt; |
output sendPacketGnt; |
|
reg [7:0] SCTxPortCntl, next_SCTxPortCntl; |
reg [7:0] SCTxPortData, next_SCTxPortData; |
wire SCTxPortRdyIn; |
reg SCTxPortRdyOut, next_SCTxPortRdyOut; |
reg SCTxPortWEnable, next_SCTxPortWEnable; |
wire clk; |
wire [7:0] directCntlCntl; |
wire [7:0] directCntlData; |
reg directCntlGnt, next_directCntlGnt; |
wire directCntlReq; |
wire directCntlWEn; |
wire rst; |
wire [7:0] sendPacketCntl; |
wire [7:0] sendPacketData; |
reg sendPacketGnt, next_sendPacketGnt; |
wire sendPacketReq; |
wire sendPacketWEn; |
|
// diagram signals declarations |
reg muxDCEn, next_muxDCEn; |
|
// BINARY ENCODED state machine: SCTxArb |
// State codes definitions: |
`define SARB1_WAIT_REQ 2'b00 |
`define SARB_SEND_PACKET 2'b01 |
`define SARB_DC 2'b10 |
`define START_SARB 2'b11 |
|
reg [1:0] CurrState_SCTxArb; |
reg [1:0] NextState_SCTxArb; |
|
// Diagram actions (continuous assignments allowed only: assign ...) |
|
// SOFController/directContol/sendPacket mux |
always @(SCTxPortRdyIn) |
begin |
SCTxPortRdyOut <= SCTxPortRdyIn; |
end |
always @(muxDCEn or |
directCntlWEn or directCntlData or directCntlCntl or |
directCntlWEn or directCntlData or directCntlCntl or |
sendPacketWEn or sendPacketData or sendPacketCntl) |
begin |
if (muxDCEn == 1'b1) |
begin |
SCTxPortWEnable <= directCntlWEn; |
SCTxPortData <= directCntlData; |
SCTxPortCntl <= directCntlCntl; |
end |
else |
begin |
SCTxPortWEnable <= sendPacketWEn; |
SCTxPortData <= sendPacketData; |
SCTxPortCntl <= sendPacketCntl; |
end |
end |
|
//-------------------------------------------------------------------- |
// Machine: SCTxArb |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (sendPacketReq or directCntlReq or sendPacketGnt or muxDCEn or directCntlGnt or CurrState_SCTxArb) |
begin : SCTxArb_NextState |
NextState_SCTxArb <= CurrState_SCTxArb; |
// Set default values for outputs and signals |
next_sendPacketGnt <= sendPacketGnt; |
next_muxDCEn <= muxDCEn; |
next_directCntlGnt <= directCntlGnt; |
case (CurrState_SCTxArb) |
`SARB1_WAIT_REQ: |
if (sendPacketReq == 1'b1) |
begin |
NextState_SCTxArb <= `SARB_SEND_PACKET; |
next_sendPacketGnt <= 1'b1; |
next_muxDCEn <= 1'b0; |
end |
else if (directCntlReq == 1'b1) |
begin |
NextState_SCTxArb <= `SARB_DC; |
next_directCntlGnt <= 1'b1; |
next_muxDCEn <= 1'b1; |
end |
`SARB_SEND_PACKET: |
if (sendPacketReq == 1'b0) |
begin |
NextState_SCTxArb <= `SARB1_WAIT_REQ; |
next_sendPacketGnt <= 1'b0; |
end |
`SARB_DC: |
if (directCntlReq == 1'b0) |
begin |
NextState_SCTxArb <= `SARB1_WAIT_REQ; |
next_directCntlGnt <= 1'b0; |
end |
`START_SARB: |
NextState_SCTxArb <= `SARB1_WAIT_REQ; |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : SCTxArb_CurrentState |
if (rst) |
CurrState_SCTxArb <= `START_SARB; |
else |
CurrState_SCTxArb <= NextState_SCTxArb; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : SCTxArb_RegOutput |
if (rst) |
begin |
muxDCEn <= 1'b0; |
sendPacketGnt <= 1'b0; |
directCntlGnt <= 1'b0; |
end |
else |
begin |
muxDCEn <= next_muxDCEn; |
sendPacketGnt <= next_sendPacketGnt; |
directCntlGnt <= next_directCntlGnt; |
end |
end |
|
endmodule |
/verilog/usbhostslave/TxFifo.v
0,0 → 1,132
////////////////////////////////////////////////////////////////////// |
//// //// |
//// TxFifo.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// parameterized TxFifo wrapper. Min depth = 2, Max depth = 65536 |
//// fifo write access via bus interface, fifo read access is direct |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module TxFifo( |
busClk, |
usbClk, |
rstSyncToBusClk, |
rstSyncToUsbClk, |
fifoREn, |
fifoEmpty, |
busAddress, |
busWriteEn, |
busStrobe_i, |
busFifoSelect, |
busDataIn, |
busDataOut, |
fifoDataOut ); |
//FIFO_DEPTH = ADDR_WIDTH^2 |
parameter FIFO_DEPTH = 64; |
parameter ADDR_WIDTH = 6; |
|
input busClk; |
input usbClk; |
input rstSyncToBusClk; |
input rstSyncToUsbClk; |
input fifoREn; |
output fifoEmpty; |
input [2:0] busAddress; |
input busWriteEn; |
input busStrobe_i; |
input busFifoSelect; |
input [7:0] busDataIn; |
output [7:0] busDataOut; |
output [7:0] fifoDataOut; |
|
wire busClk; |
wire usbClk; |
wire rstSyncToBusClk; |
wire rstSyncToUsbClk; |
wire fifoREn; |
wire fifoEmpty; |
wire [2:0] busAddress; |
wire busWriteEn; |
wire busStrobe_i; |
wire busFifoSelect; |
wire [7:0] busDataIn; |
wire [7:0] busDataOut; |
wire [7:0] fifoDataOut; |
|
//internal wires and regs |
wire fifoWEn; |
wire forceEmptySyncToUsbClk; |
wire forceEmptySyncToBusClk; |
wire [15:0] numElementsInFifo; |
wire fifoFull; |
|
fifoRTL #(8, FIFO_DEPTH, ADDR_WIDTH) u_fifo( |
.wrClk(busClk), |
.rdClk(usbClk), |
.rstSyncToWrClk(rstSyncToBusClk), |
.rstSyncToRdClk(rstSyncToUsbClk), |
.dataIn(busDataIn), |
.dataOut(fifoDataOut), |
.fifoWEn(fifoWEn), |
.fifoREn(fifoREn), |
.fifoFull(fifoFull), |
.fifoEmpty(fifoEmpty), |
.forceEmptySyncToWrClk(forceEmptySyncToBusClk), |
.forceEmptySyncToRdClk(forceEmptySyncToUsbClk), |
.numElementsInFifo(numElementsInFifo) ); |
|
TxfifoBI u_TxfifoBI( |
.address(busAddress), |
.writeEn(busWriteEn), |
.strobe_i(busStrobe_i), |
.busClk(busClk), |
.usbClk(usbClk), |
.rstSyncToBusClk(rstSyncToBusClk), |
.fifoSelect(busFifoSelect), |
.busDataIn(busDataIn), |
.busDataOut(busDataOut), |
.fifoWEn(fifoWEn), |
.forceEmptySyncToBusClk(forceEmptySyncToBusClk), |
.forceEmptySyncToUsbClk(forceEmptySyncToUsbClk), |
.numElementsInFifo(numElementsInFifo) |
); |
|
endmodule |
/verilog/usbhostslave/USBSlaveControlBI.v
0,0 → 1,714
////////////////////////////////////////////////////////////////////// |
//// //// |
//// USBSlaveControlBI.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_slavecontrol_h.v" |
|
module USBSlaveControlBI (address, dataIn, dataOut, writeEn, |
strobe_i, |
busClk, |
rstSyncToBusClk, |
usbClk, |
rstSyncToUsbClk, |
SOFRxedIntOut, resetEventIntOut, resumeIntOut, transDoneIntOut, NAKSentIntOut, vBusDetIntOut, |
endP0TransTypeReg, endP0NAKTransTypeReg, |
endP1TransTypeReg, endP1NAKTransTypeReg, |
endP2TransTypeReg, endP2NAKTransTypeReg, |
endP3TransTypeReg, endP3NAKTransTypeReg, |
endP0ControlReg, |
endP1ControlReg, |
endP2ControlReg, |
endP3ControlReg, |
EP0StatusReg, |
EP1StatusReg, |
EP2StatusReg, |
EP3StatusReg, |
SCAddrReg, frameNum, |
connectStateIn, |
vBusDetectIn, |
SOFRxedIn, resetEventIn, resumeIntIn, transDoneIn, NAKSentIn, |
slaveControlSelect, |
clrEP0Ready, clrEP1Ready, clrEP2Ready, clrEP3Ready, |
TxLineState, |
LineDirectControlEn, |
fullSpeedPol, |
fullSpeedRate, |
connectSlaveToHost, |
SCGlobalEn |
); |
input [4:0] address; |
input [7:0] dataIn; |
input writeEn; |
input strobe_i; |
input busClk; |
input rstSyncToBusClk; |
input usbClk; |
input rstSyncToUsbClk; |
output [7:0] dataOut; |
output SOFRxedIntOut; |
output resetEventIntOut; |
output resumeIntOut; |
output transDoneIntOut; |
output NAKSentIntOut; |
output vBusDetIntOut; |
|
input [1:0] endP0TransTypeReg; |
input [1:0] endP0NAKTransTypeReg; |
input [1:0] endP1TransTypeReg; |
input [1:0] endP1NAKTransTypeReg; |
input [1:0] endP2TransTypeReg; |
input [1:0] endP2NAKTransTypeReg; |
input [1:0] endP3TransTypeReg; |
input [1:0] endP3NAKTransTypeReg; |
output [4:0] endP0ControlReg; |
output [4:0] endP1ControlReg; |
output [4:0] endP2ControlReg; |
output [4:0] endP3ControlReg; |
input [7:0] EP0StatusReg; |
input [7:0] EP1StatusReg; |
input [7:0] EP2StatusReg; |
input [7:0] EP3StatusReg; |
output [6:0] SCAddrReg; |
input [10:0] frameNum; |
input [1:0] connectStateIn; |
input vBusDetectIn; |
input SOFRxedIn; |
input resetEventIn; |
input resumeIntIn; |
input transDoneIn; |
input NAKSentIn; |
input slaveControlSelect; |
input clrEP0Ready; |
input clrEP1Ready; |
input clrEP2Ready; |
input clrEP3Ready; |
output [1:0] TxLineState; |
output LineDirectControlEn; |
output fullSpeedPol; |
output fullSpeedRate; |
output connectSlaveToHost; |
output SCGlobalEn; |
|
wire [4:0] address; |
wire [7:0] dataIn; |
wire writeEn; |
wire strobe_i; |
wire busClk; |
wire rstSyncToBusClk; |
wire usbClk; |
wire rstSyncToUsbClk; |
reg [7:0] dataOut; |
|
reg SOFRxedIntOut; |
reg resetEventIntOut; |
reg resumeIntOut; |
reg transDoneIntOut; |
reg NAKSentIntOut; |
reg vBusDetIntOut; |
|
wire [1:0] endP0TransTypeReg; |
wire [1:0] endP0NAKTransTypeReg; |
wire [1:0] endP1TransTypeReg; |
wire [1:0] endP1NAKTransTypeReg; |
wire [1:0] endP2TransTypeReg; |
wire [1:0] endP2NAKTransTypeReg; |
wire [1:0] endP3TransTypeReg; |
wire [1:0] endP3NAKTransTypeReg; |
reg [4:0] endP0ControlReg; |
reg [4:0] endP0ControlReg1; |
reg [4:0] endP1ControlReg; |
reg [4:0] endP1ControlReg1; |
reg [4:0] endP2ControlReg; |
reg [4:0] endP2ControlReg1; |
reg [4:0] endP3ControlReg; |
reg [4:0] endP3ControlReg1; |
wire [7:0] EP0StatusReg; |
wire [7:0] EP1StatusReg; |
wire [7:0] EP2StatusReg; |
wire [7:0] EP3StatusReg; |
reg [6:0] SCAddrReg; |
reg [3:0] TxEndPReg; |
wire [10:0] frameNum; |
wire [1:0] connectStateIn; |
|
wire SOFRxedIn; |
wire resetEventIn; |
wire resumeIntIn; |
wire transDoneIn; |
wire NAKSentIn; |
wire slaveControlSelect; |
wire clrEP0Ready; |
wire clrEP1Ready; |
wire clrEP2Ready; |
wire clrEP3Ready; |
reg [1:0] TxLineState; |
reg [1:0] TxLineState_reg1; |
reg LineDirectControlEn; |
reg LineDirectControlEn_reg1; |
reg fullSpeedPol; |
reg fullSpeedPol_reg1; |
reg fullSpeedRate; |
reg fullSpeedRate_reg1; |
reg connectSlaveToHost; |
reg connectSlaveToHost_reg1; |
reg SCGlobalEn; |
reg SCGlobalEn_reg1; |
|
//internal wire and regs |
reg [6:0] SCControlReg; |
reg clrVBusDetReq; |
reg clrNAKReq; |
reg clrSOFReq; |
reg clrResetReq; |
reg clrResInReq; |
reg clrTransDoneReq; |
reg SOFRxedInt; |
reg resetEventInt; |
reg resumeInt; |
reg transDoneInt; |
reg vBusDetInt; |
reg NAKSentInt; |
reg [5:0] interruptMaskReg; |
reg EP0SetReady; |
reg EP1SetReady; |
reg EP2SetReady; |
reg EP3SetReady; |
reg EP0SendStall; |
reg EP1SendStall; |
reg EP2SendStall; |
reg EP3SendStall; |
reg EP0IsoEn; |
reg EP1IsoEn; |
reg EP2IsoEn; |
reg EP3IsoEn; |
reg EP0DataSequence; |
reg EP1DataSequence; |
reg EP2DataSequence; |
reg EP3DataSequence; |
reg EP0Enable; |
reg EP1Enable; |
reg EP2Enable; |
reg EP3Enable; |
reg EP0Ready; |
reg EP1Ready; |
reg EP2Ready; |
reg EP3Ready; |
reg [2:0] SOFRxedInExtend; |
reg [2:0] resetEventInExtend; |
reg [2:0] resumeIntInExtend; |
reg [2:0] transDoneInExtend; |
reg [2:0] NAKSentInExtend; |
reg [2:0] clrEP0ReadyExtend; |
reg [2:0] clrEP1ReadyExtend; |
reg [2:0] clrEP2ReadyExtend; |
reg [2:0] clrEP3ReadyExtend; |
|
|
//clock domain crossing sync registers |
//STB = Sync To Busclk |
reg [4:0] endP0ControlRegSTB; |
reg [4:0] endP1ControlRegSTB; |
reg [4:0] endP2ControlRegSTB; |
reg [4:0] endP3ControlRegSTB; |
reg [2:0] NAKSentInSTB; |
reg [2:0] SOFRxedInSTB; |
reg [2:0] resetEventInSTB; |
reg [2:0] resumeIntInSTB; |
reg [2:0] transDoneInSTB; |
reg [2:0] clrEP0ReadySTB; |
reg [2:0] clrEP1ReadySTB; |
reg [2:0] clrEP2ReadySTB; |
reg [2:0] clrEP3ReadySTB; |
reg SCGlobalEnSTB; |
reg [1:0] TxLineStateSTB; |
reg LineDirectControlEnSTB; |
reg fullSpeedPolSTB; |
reg fullSpeedRateSTB; |
reg connectSlaveToHostSTB; |
reg [7:0] EP0StatusRegSTB; |
reg [7:0] EP0StatusRegSTB_reg1; |
reg [7:0] EP1StatusRegSTB; |
reg [7:0] EP1StatusRegSTB_reg1; |
reg [7:0] EP2StatusRegSTB; |
reg [7:0] EP2StatusRegSTB_reg1; |
reg [7:0] EP3StatusRegSTB; |
reg [7:0] EP3StatusRegSTB_reg1; |
reg [1:0] endP0TransTypeRegSTB; |
reg [1:0] endP0TransTypeRegSTB_reg1; |
reg [1:0] endP0NAKTransTypeRegSTB; |
reg [1:0] endP0NAKTransTypeRegSTB_reg1; |
reg [1:0] endP1TransTypeRegSTB; |
reg [1:0] endP1TransTypeRegSTB_reg1; |
reg [1:0] endP1NAKTransTypeRegSTB; |
reg [1:0] endP1NAKTransTypeRegSTB_reg1; |
reg [1:0] endP2TransTypeRegSTB; |
reg [1:0] endP2TransTypeRegSTB_reg1; |
reg [1:0] endP2NAKTransTypeRegSTB; |
reg [1:0] endP2NAKTransTypeRegSTB_reg1; |
reg [1:0] endP3TransTypeRegSTB; |
reg [1:0] endP3TransTypeRegSTB_reg1; |
reg [1:0] endP3NAKTransTypeRegSTB; |
reg [1:0] endP3NAKTransTypeRegSTB_reg1; |
reg [10:0] frameNumSTB; |
reg [10:0] frameNumSTB_reg1; |
reg [2:0] vBusDetectInSTB; |
reg [1:0] connectStateInSTB; |
reg [1:0] connectStateInSTB_reg1; |
|
|
//sync write demux |
always @(posedge busClk) |
begin |
if (rstSyncToBusClk == 1'b1) begin |
EP0IsoEn <= 1'b0; |
EP0SendStall <= 1'b0; |
EP0DataSequence <= 1'b0; |
EP0Enable <= 1'b0; |
EP1IsoEn <= 1'b0; |
EP1SendStall <= 1'b0; |
EP1DataSequence <= 1'b0; |
EP1Enable <= 1'b0; |
EP2IsoEn <= 1'b0; |
EP2SendStall <= 1'b0; |
EP2DataSequence <= 1'b0; |
EP2Enable <= 1'b0; |
EP3IsoEn <= 1'b0; |
EP3SendStall <= 1'b0; |
EP3DataSequence <= 1'b0; |
EP3Enable <= 1'b0; |
SCControlReg <= 7'h00; |
SCAddrReg <= 7'h00; |
interruptMaskReg <= 6'h00; |
end |
else begin |
clrVBusDetReq <= 1'b0; |
clrNAKReq <= 1'b0; |
clrSOFReq <= 1'b0; |
clrResetReq <= 1'b0; |
clrResInReq <= 1'b0; |
clrTransDoneReq <= 1'b0; |
EP0SetReady <= 1'b0; |
EP1SetReady <= 1'b0; |
EP2SetReady <= 1'b0; |
EP3SetReady <= 1'b0; |
if (writeEn == 1'b1 && strobe_i == 1'b1 && slaveControlSelect == 1'b1) |
begin |
case (address) |
`EP0_CTRL_REG : begin |
EP0IsoEn <= dataIn[`ENDPOINT_ISO_ENABLE_BIT]; |
EP0SendStall <= dataIn[`ENDPOINT_SEND_STALL_BIT]; |
EP0DataSequence <= dataIn[`ENDPOINT_OUTDATA_SEQUENCE_BIT]; |
EP0SetReady <= dataIn[`ENDPOINT_READY_BIT]; |
EP0Enable <= dataIn[`ENDPOINT_ENABLE_BIT]; |
end |
`EP1_CTRL_REG : begin |
EP1IsoEn <= dataIn[`ENDPOINT_ISO_ENABLE_BIT]; |
EP1SendStall <= dataIn[`ENDPOINT_SEND_STALL_BIT]; |
EP1DataSequence <= dataIn[`ENDPOINT_OUTDATA_SEQUENCE_BIT]; |
EP1SetReady <= dataIn[`ENDPOINT_READY_BIT]; |
EP1Enable <= dataIn[`ENDPOINT_ENABLE_BIT]; |
end |
`EP2_CTRL_REG : begin |
EP2IsoEn <= dataIn[`ENDPOINT_ISO_ENABLE_BIT]; |
EP2SendStall <= dataIn[`ENDPOINT_SEND_STALL_BIT]; |
EP2DataSequence <= dataIn[`ENDPOINT_OUTDATA_SEQUENCE_BIT]; |
EP2SetReady <= dataIn[`ENDPOINT_READY_BIT]; |
EP2Enable <= dataIn[`ENDPOINT_ENABLE_BIT]; |
end |
`EP3_CTRL_REG : begin |
EP3IsoEn <= dataIn[`ENDPOINT_ISO_ENABLE_BIT]; |
EP3SendStall <= dataIn[`ENDPOINT_SEND_STALL_BIT]; |
EP3DataSequence <= dataIn[`ENDPOINT_OUTDATA_SEQUENCE_BIT]; |
EP3SetReady <= dataIn[`ENDPOINT_READY_BIT]; |
EP3Enable <= dataIn[`ENDPOINT_ENABLE_BIT]; |
end |
`SC_CONTROL_REG : SCControlReg <= dataIn[6:0]; |
`SC_ADDRESS : SCAddrReg <= dataIn[6:0]; |
`SC_INTERRUPT_STATUS_REG : begin |
clrVBusDetReq <= dataIn[`VBUS_DET_INT_BIT]; |
clrNAKReq <= dataIn[`NAK_SENT_INT_BIT]; |
clrSOFReq <= dataIn[`SOF_RECEIVED_BIT]; |
clrResetReq <= dataIn[`RESET_EVENT_BIT]; |
clrResInReq <= dataIn[`RESUME_INT_BIT]; |
clrTransDoneReq <= dataIn[`TRANS_DONE_BIT]; |
end |
`SC_INTERRUPT_MASK_REG : interruptMaskReg <= dataIn[5:0]; |
endcase |
end |
end |
end |
|
//interrupt control |
always @(posedge busClk) |
begin |
if (rstSyncToBusClk == 1'b1) begin |
vBusDetInt <= 1'b0; |
NAKSentInt <= 1'b0; |
SOFRxedInt <= 1'b0; |
resetEventInt <= 1'b0; |
resumeInt <= 1'b0; |
transDoneInt <= 1'b0; |
end |
else begin |
if (vBusDetectInSTB[0] != vBusDetectInSTB[1]) |
vBusDetInt <= 1'b1; |
else if (clrVBusDetReq == 1'b1) |
vBusDetInt <= 1'b0; |
|
if (NAKSentInSTB[1] == 1'b1 && NAKSentInSTB[0] == 1'b0) |
NAKSentInt <= 1'b1; |
else if (clrNAKReq == 1'b1) |
NAKSentInt <= 1'b0; |
|
if (SOFRxedInSTB[1] == 1'b1 && SOFRxedInSTB[0] == 1'b0) |
SOFRxedInt <= 1'b1; |
else if (clrSOFReq == 1'b1) |
SOFRxedInt <= 1'b0; |
|
if (resetEventInSTB[1] == 1'b1 && resetEventInSTB[0] == 1'b0) |
resetEventInt <= 1'b1; |
else if (clrResetReq == 1'b1) |
resetEventInt <= 1'b0; |
|
if (resumeIntInSTB[1] == 1'b1 && resumeIntInSTB[0] == 1'b0) |
resumeInt <= 1'b1; |
else if (clrResInReq == 1'b1) |
resumeInt <= 1'b0; |
|
if (transDoneInSTB[1] == 1'b1 && transDoneInSTB[0] == 1'b0) |
transDoneInt <= 1'b1; |
else if (clrTransDoneReq == 1'b1) |
transDoneInt <= 1'b0; |
end |
end |
|
//mask interrupts |
always @(*) begin |
transDoneIntOut <= transDoneInt & interruptMaskReg[`TRANS_DONE_BIT]; |
resumeIntOut <= resumeInt & interruptMaskReg[`RESUME_INT_BIT]; |
resetEventIntOut <= resetEventInt & interruptMaskReg[`RESET_EVENT_BIT]; |
SOFRxedIntOut <= SOFRxedInt & interruptMaskReg[`SOF_RECEIVED_BIT]; |
NAKSentIntOut <= NAKSentInt & interruptMaskReg[`NAK_SENT_INT_BIT]; |
vBusDetIntOut <= vBusDetInt & interruptMaskReg[`VBUS_DET_INT_BIT]; |
end |
|
//end point ready, set/clear |
//Since 'busClk' can be a higher freq than 'usbClk', |
//'EP0SetReady' etc must be delayed with respect to other control signals, thus |
//ensuring that control signals have been clocked through to 'usbClk' clock |
//domain before the ready is asserted. |
//Not sure this is required because there is at least two 'usbClk' ticks between |
//detection of 'EP0Ready' and sampling of related control signals. |
always @(posedge busClk) |
begin |
if (rstSyncToBusClk == 1'b1) begin |
EP0Ready <= 1'b0; |
EP1Ready <= 1'b0; |
EP2Ready <= 1'b0; |
EP3Ready <= 1'b0; |
end |
else begin |
if (EP0SetReady == 1'b1) |
EP0Ready <= 1'b1; |
else if (clrEP0ReadySTB[1] == 1'b1 && clrEP0ReadySTB[0] == 1'b0) |
EP0Ready <= 1'b0; |
|
if (EP1SetReady == 1'b1) |
EP1Ready <= 1'b1; |
else if (clrEP1ReadySTB[1] == 1'b1 && clrEP1ReadySTB[0] == 1'b0) |
EP1Ready <= 1'b0; |
|
if (EP2SetReady == 1'b1) |
EP2Ready <= 1'b1; |
else if (clrEP2ReadySTB[1] == 1'b1 && clrEP2ReadySTB[0] == 1'b0) |
EP2Ready <= 1'b0; |
|
if (EP3SetReady == 1'b1) |
EP3Ready <= 1'b1; |
else if (clrEP3ReadySTB[1] == 1'b1 && clrEP3ReadySTB[0] == 1'b0) |
EP3Ready <= 1'b0; |
end |
end |
|
//break out control signals |
always @(SCControlReg) begin |
SCGlobalEnSTB <= SCControlReg[`SC_GLOBAL_ENABLE_BIT]; |
TxLineStateSTB <= SCControlReg[`SC_TX_LINE_STATE_MSBIT:`SC_TX_LINE_STATE_LSBIT]; |
LineDirectControlEnSTB <= SCControlReg[`SC_DIRECT_CONTROL_BIT]; |
fullSpeedPolSTB <= SCControlReg[`SC_FULL_SPEED_LINE_POLARITY_BIT]; |
fullSpeedRateSTB <= SCControlReg[`SC_FULL_SPEED_LINE_RATE_BIT]; |
connectSlaveToHostSTB <= SCControlReg[`SC_CONNECT_TO_HOST_BIT]; |
end |
|
//combine endpoint control signals |
always @(*) |
begin |
endP0ControlRegSTB <= {EP0IsoEn, EP0SendStall, EP0DataSequence, EP0Ready, EP0Enable}; |
endP1ControlRegSTB <= {EP1IsoEn, EP1SendStall, EP1DataSequence, EP1Ready, EP1Enable}; |
endP2ControlRegSTB <= {EP2IsoEn, EP2SendStall, EP2DataSequence, EP2Ready, EP2Enable}; |
endP3ControlRegSTB <= {EP3IsoEn, EP3SendStall, EP3DataSequence, EP3Ready, EP3Enable}; |
end |
|
|
// async read mux |
always @(*) |
begin |
case (address) |
`EP0_CTRL_REG : dataOut <= endP0ControlRegSTB; |
`EP0_STS_REG : dataOut <= EP0StatusRegSTB; |
`EP0_TRAN_TYPE_STS_REG : dataOut <= endP0TransTypeRegSTB; |
`EP0_NAK_TRAN_TYPE_STS_REG : dataOut <= endP0NAKTransTypeRegSTB; |
`EP1_CTRL_REG : dataOut <= endP1ControlRegSTB; |
`EP1_STS_REG : dataOut <= EP1StatusRegSTB; |
`EP1_TRAN_TYPE_STS_REG : dataOut <= endP1TransTypeRegSTB; |
`EP1_NAK_TRAN_TYPE_STS_REG : dataOut <= endP1NAKTransTypeRegSTB; |
`EP2_CTRL_REG : dataOut <= endP2ControlRegSTB; |
`EP2_STS_REG : dataOut <= EP2StatusRegSTB; |
`EP2_TRAN_TYPE_STS_REG : dataOut <= endP2TransTypeRegSTB; |
`EP2_NAK_TRAN_TYPE_STS_REG : dataOut <= endP2NAKTransTypeRegSTB; |
`EP3_CTRL_REG : dataOut <= endP3ControlRegSTB; |
`EP3_STS_REG : dataOut <= EP3StatusRegSTB; |
`EP3_TRAN_TYPE_STS_REG : dataOut <= endP3TransTypeRegSTB; |
`EP3_NAK_TRAN_TYPE_STS_REG : dataOut <= endP3NAKTransTypeRegSTB; |
`SC_CONTROL_REG : dataOut <= SCControlReg; |
`SC_LINE_STATUS_REG : dataOut <= {5'b00000, vBusDetectInSTB[0], connectStateInSTB}; |
`SC_INTERRUPT_STATUS_REG : dataOut <= {2'b00, vBusDetInt, NAKSentInt, SOFRxedInt, resetEventInt, resumeInt, transDoneInt}; |
`SC_INTERRUPT_MASK_REG : dataOut <= {2'b00, interruptMaskReg}; |
`SC_ADDRESS : dataOut <= {1'b0, SCAddrReg}; |
`SC_FRAME_NUM_MSP : dataOut <= {5'b00000, frameNumSTB[10:8]}; |
`SC_FRAME_NUM_LSP : dataOut <= frameNumSTB[7:0]; |
default: dataOut <= 8'h00; |
endcase |
end |
|
|
//Extend SOFRxedIn, resetEventIn, resumeIntIn, transDoneIn, NAKSentIn from 1 tick |
//pulses to 3 tick pulses |
always @(posedge usbClk) begin |
if (rstSyncToUsbClk == 1'b1) begin |
SOFRxedInExtend <= 3'b000; |
resetEventInExtend <= 3'b000; |
resumeIntInExtend <= 3'b000; |
transDoneInExtend <= 3'b000; |
NAKSentInExtend <= 3'b000; |
clrEP0ReadyExtend <= 3'b000; |
clrEP1ReadyExtend <= 3'b000; |
clrEP2ReadyExtend <= 3'b000; |
clrEP3ReadyExtend <= 3'b000; |
end |
else begin |
if (SOFRxedIn == 1'b1) |
SOFRxedInExtend <= 3'b111; |
else |
SOFRxedInExtend <= {1'b0, SOFRxedInExtend[2:1]}; |
if (resetEventIn == 1'b1) |
resetEventInExtend <= 3'b111; |
else |
resetEventInExtend <= {1'b0, resetEventInExtend[2:1]}; |
if (resumeIntIn == 1'b1) |
resumeIntInExtend <= 3'b111; |
else |
resumeIntInExtend <= {1'b0, resumeIntInExtend[2:1]}; |
if (transDoneIn == 1'b1) |
transDoneInExtend <= 3'b111; |
else |
transDoneInExtend <= {1'b0, transDoneInExtend[2:1]}; |
if (NAKSentIn == 1'b1) |
NAKSentInExtend <= 3'b111; |
else |
NAKSentInExtend <= {1'b0, NAKSentInExtend[2:1]}; |
if (clrEP0Ready == 1'b1) |
clrEP0ReadyExtend <= 3'b111; |
else |
clrEP0ReadyExtend <= {1'b0, clrEP0ReadyExtend[2:1]}; |
if (clrEP1Ready == 1'b1) |
clrEP1ReadyExtend <= 3'b111; |
else |
clrEP1ReadyExtend <= {1'b0, clrEP1ReadyExtend[2:1]}; |
if (clrEP2Ready == 1'b1) |
clrEP2ReadyExtend <= 3'b111; |
else |
clrEP2ReadyExtend <= {1'b0, clrEP2ReadyExtend[2:1]}; |
if (clrEP3Ready == 1'b1) |
clrEP3ReadyExtend <= 3'b111; |
else |
clrEP3ReadyExtend <= {1'b0, clrEP3ReadyExtend[2:1]}; |
end |
end |
|
//re-sync from busClk to usbClk. |
always @(posedge usbClk) begin |
if (rstSyncToUsbClk == 1'b1) begin |
endP0ControlReg <= {5{1'b0}}; |
endP0ControlReg1 <= {5{1'b0}}; |
endP1ControlReg <= {5{1'b0}}; |
endP1ControlReg1 <= {5{1'b0}}; |
endP2ControlReg <= {5{1'b0}}; |
endP2ControlReg1 <= {5{1'b0}}; |
endP3ControlReg <= {5{1'b0}}; |
endP3ControlReg1 <= {5{1'b0}}; |
SCGlobalEn <= 1'b0; |
SCGlobalEn_reg1 <= 1'b0; |
TxLineState <= 2'b00; |
TxLineState_reg1 <= 2'b00; |
LineDirectControlEn <= 1'b0; |
LineDirectControlEn_reg1 <= 1'b0; |
fullSpeedPol <= 1'b0; |
fullSpeedPol_reg1 <= 1'b0; |
fullSpeedRate <= 1'b0; |
fullSpeedRate_reg1 <= 1'b0; |
connectSlaveToHost <= 1'b0; |
connectSlaveToHost_reg1 <= 1'b0; |
end |
else begin |
endP0ControlReg1 <= endP0ControlRegSTB; |
endP0ControlReg <= endP0ControlReg1; |
endP1ControlReg1 <= endP1ControlRegSTB; |
endP1ControlReg <= endP1ControlReg1; |
endP2ControlReg1 <= endP2ControlRegSTB; |
endP2ControlReg <= endP2ControlReg1; |
endP3ControlReg1 <= endP3ControlRegSTB; |
endP3ControlReg <= endP3ControlReg1; |
SCGlobalEn_reg1 <= SCGlobalEnSTB; |
SCGlobalEn <= SCGlobalEn_reg1; |
TxLineState_reg1 <= TxLineStateSTB; |
TxLineState <= TxLineState_reg1; |
LineDirectControlEn_reg1 <= LineDirectControlEnSTB; |
LineDirectControlEn <= LineDirectControlEn_reg1; |
fullSpeedPol_reg1 <= fullSpeedPolSTB; |
fullSpeedPol <= fullSpeedPol_reg1; |
fullSpeedRate_reg1 <= fullSpeedRateSTB; |
fullSpeedRate <= fullSpeedRate_reg1; |
connectSlaveToHost_reg1 <= connectSlaveToHostSTB; |
connectSlaveToHost <= connectSlaveToHost_reg1; |
end |
end |
|
//re-sync from usbClk and async inputs to busClk. Since 'NAKSentIn', 'SOFRxedIn' etc |
//are only asserted for 3 usbClk ticks |
//busClk freq must be greater than usbClk/3 (plus some allowance for setup and hold) freq |
always @(posedge busClk) begin |
if (rstSyncToBusClk == 1'b1) begin |
vBusDetectInSTB <= 3'b000; |
NAKSentInSTB <= 3'b000; |
SOFRxedInSTB <= 3'b000; |
resetEventInSTB <= 3'b000; |
resumeIntInSTB <= 3'b000; |
transDoneInSTB <= 3'b000; |
clrEP0ReadySTB <= 3'b000; |
clrEP1ReadySTB <= 3'b000; |
clrEP2ReadySTB <= 3'b000; |
clrEP3ReadySTB <= 3'b000; |
EP0StatusRegSTB <= 8'h00; |
EP0StatusRegSTB_reg1 <= 8'h00; |
EP1StatusRegSTB <= 8'h00; |
EP1StatusRegSTB_reg1 <= 8'h00; |
EP2StatusRegSTB <= 8'h00; |
EP2StatusRegSTB_reg1 <= 8'h00; |
EP3StatusRegSTB <= 8'h00; |
EP3StatusRegSTB_reg1 <= 8'h00; |
endP0TransTypeRegSTB <= 2'b00; |
endP0TransTypeRegSTB_reg1 <= 2'b00; |
endP1TransTypeRegSTB <= 2'b00; |
endP1TransTypeRegSTB_reg1 <= 2'b00; |
endP2TransTypeRegSTB <= 2'b00; |
endP2TransTypeRegSTB_reg1 <= 2'b00; |
endP3TransTypeRegSTB <= 2'b00; |
endP3TransTypeRegSTB_reg1 <= 2'b00; |
endP0NAKTransTypeRegSTB <= 2'b00; |
endP0NAKTransTypeRegSTB_reg1 <= 2'b00; |
endP1NAKTransTypeRegSTB <= 2'b00; |
endP1NAKTransTypeRegSTB_reg1 <= 2'b00; |
endP2NAKTransTypeRegSTB <= 2'b00; |
endP2NAKTransTypeRegSTB_reg1 <= 2'b00; |
endP3NAKTransTypeRegSTB <= 2'b00; |
endP3NAKTransTypeRegSTB_reg1 <= 2'b00; |
frameNumSTB <= {11{1'b0}}; |
frameNumSTB_reg1 <= {11{1'b0}}; |
connectStateInSTB <= 2'b00; |
connectStateInSTB_reg1 <= 2'b00; |
end |
else begin |
vBusDetectInSTB <= {vBusDetectIn, vBusDetectInSTB[2:1]}; |
NAKSentInSTB <= {NAKSentInExtend[0], NAKSentInSTB[2:1]}; |
SOFRxedInSTB <= {SOFRxedInExtend[0], SOFRxedInSTB[2:1]}; |
resetEventInSTB <= {resetEventInExtend[0], resetEventInSTB[2:1]}; |
resumeIntInSTB <= {resumeIntInExtend[0], resumeIntInSTB[2:1]}; |
transDoneInSTB <= {transDoneInExtend[0], transDoneInSTB[2:1]}; |
clrEP0ReadySTB <= {clrEP0ReadyExtend[0], clrEP0ReadySTB[2:1]}; |
clrEP1ReadySTB <= {clrEP1ReadyExtend[0], clrEP1ReadySTB[2:1]}; |
clrEP2ReadySTB <= {clrEP2ReadyExtend[0], clrEP2ReadySTB[2:1]}; |
clrEP3ReadySTB <= {clrEP3ReadyExtend[0], clrEP3ReadySTB[2:1]}; |
EP0StatusRegSTB_reg1 <= EP0StatusReg; |
EP0StatusRegSTB <= EP0StatusRegSTB_reg1; |
EP1StatusRegSTB_reg1 <= EP1StatusReg; |
EP1StatusRegSTB <= EP1StatusRegSTB_reg1; |
EP2StatusRegSTB_reg1 <= EP2StatusReg; |
EP2StatusRegSTB <= EP2StatusRegSTB_reg1; |
EP3StatusRegSTB_reg1 <= EP3StatusReg; |
EP3StatusRegSTB <= EP3StatusRegSTB_reg1; |
endP0TransTypeRegSTB_reg1 <= endP0TransTypeReg; |
endP0TransTypeRegSTB <= endP0TransTypeRegSTB_reg1; |
endP1TransTypeRegSTB_reg1 <= endP1TransTypeReg; |
endP1TransTypeRegSTB <= endP1TransTypeRegSTB_reg1; |
endP2TransTypeRegSTB_reg1 <= endP2TransTypeReg; |
endP2TransTypeRegSTB <= endP2TransTypeRegSTB_reg1; |
endP3TransTypeRegSTB_reg1 <= endP3TransTypeReg; |
endP3TransTypeRegSTB <= endP3TransTypeRegSTB_reg1; |
endP0NAKTransTypeRegSTB_reg1 <= endP0NAKTransTypeReg; |
endP0NAKTransTypeRegSTB <= endP0NAKTransTypeRegSTB_reg1; |
endP1NAKTransTypeRegSTB_reg1 <= endP1NAKTransTypeReg; |
endP1NAKTransTypeRegSTB <= endP1NAKTransTypeRegSTB_reg1; |
endP2NAKTransTypeRegSTB_reg1 <= endP2NAKTransTypeReg; |
endP2NAKTransTypeRegSTB <= endP2NAKTransTypeRegSTB_reg1; |
endP3NAKTransTypeRegSTB_reg1 <= endP3NAKTransTypeReg; |
endP3NAKTransTypeRegSTB <= endP3NAKTransTypeRegSTB_reg1; |
frameNumSTB_reg1 <= frameNum; |
frameNumSTB <= frameNumSTB_reg1; |
connectStateInSTB_reg1 <= connectStateIn; |
connectStateInSTB <= connectStateInSTB_reg1; |
end |
end |
|
|
endmodule |
/verilog/usbhostslave/hostSlaveMux.v
0,0 → 1,197
////////////////////////////////////////////////////////////////////// |
//// //// |
//// hostSlaveMux.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// Controls the select line for the mux that enables the sharing |
//// of a single SerialInterfaceEgine between the hostController |
//// and slaveController |
//// Also a dumping area for any features common to host and slave |
//// operation. That is reset control and version number report. |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
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 |
/verilog/usbhostslave/slaveGetPacket.v
0,0 → 1,357
|
// File : ../RTL/slaveController/slaveGetpacket.v |
// Generated : 11/10/06 05:37:25 |
// From : ../RTL/slaveController/slaveGetpacket.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// slaveGetPacket |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
`include "usbhostslave_constants_h.v" |
|
module slaveGetPacket (ACKRxed, CRCError, RXDataIn, RXDataValid, RXFifoData, RXFifoFull, RXFifoWEn, RXOverflow, RXPacketRdy, RXStreamStatusIn, RXTimeOut, RxPID, SIERxTimeOut, SIERxTimeOutEn, bitStuffError, clk, dataSequence, endPointReady, getPacketEn, rst); |
input [7:0] RXDataIn; |
input RXDataValid; |
input RXFifoFull; |
input [7:0] RXStreamStatusIn; |
input SIERxTimeOut; // Single cycle pulse |
input clk; |
input endPointReady; |
input getPacketEn; |
input rst; |
output ACKRxed; |
output CRCError; |
output [7:0] RXFifoData; |
output RXFifoWEn; |
output RXOverflow; |
output RXPacketRdy; |
output RXTimeOut; |
output [3:0] RxPID; |
output SIERxTimeOutEn; |
output bitStuffError; |
output dataSequence; |
|
reg ACKRxed, next_ACKRxed; |
reg CRCError, next_CRCError; |
wire [7:0] RXDataIn; |
wire RXDataValid; |
reg [7:0] RXFifoData, next_RXFifoData; |
wire RXFifoFull; |
reg RXFifoWEn, next_RXFifoWEn; |
reg RXOverflow, next_RXOverflow; |
reg RXPacketRdy, next_RXPacketRdy; |
wire [7:0] RXStreamStatusIn; |
reg RXTimeOut, next_RXTimeOut; |
reg [3:0] RxPID, next_RxPID; |
wire SIERxTimeOut; |
reg SIERxTimeOutEn, next_SIERxTimeOutEn; |
reg bitStuffError, next_bitStuffError; |
wire clk; |
reg dataSequence, next_dataSequence; |
wire endPointReady; |
wire getPacketEn; |
wire rst; |
|
// diagram signals declarations |
reg [7:0]RXByteOld, next_RXByteOld; |
reg [7:0]RXByteOldest, next_RXByteOldest; |
reg [7:0]RXByte, next_RXByte; |
reg [7:0]RXStreamStatus, next_RXStreamStatus; |
|
// BINARY ENCODED state machine: slvGetPkt |
// State codes definitions: |
`define PROC_PKT_CHK_PID 5'b00000 |
`define PROC_PKT_HS 5'b00001 |
`define PROC_PKT_DATA_W_D1 5'b00010 |
`define PROC_PKT_DATA_CHK_D1 5'b00011 |
`define PROC_PKT_DATA_W_D2 5'b00100 |
`define PROC_PKT_DATA_FIN 5'b00101 |
`define PROC_PKT_DATA_CHK_D2 5'b00110 |
`define PROC_PKT_DATA_W_D3 5'b00111 |
`define PROC_PKT_DATA_CHK_D3 5'b01000 |
`define PROC_PKT_DATA_LOOP_CHK_FIFO 5'b01001 |
`define PROC_PKT_DATA_LOOP_FIFO_FULL 5'b01010 |
`define PROC_PKT_DATA_LOOP_W_D 5'b01011 |
`define START_GP 5'b01100 |
`define WAIT_PKT 5'b01101 |
`define CHK_PKT_START 5'b01110 |
`define WAIT_EN 5'b01111 |
`define PKT_RDY 5'b10000 |
`define PROC_PKT_DATA_LOOP_DELAY 5'b10001 |
`define PROC_PKT_DATA_LOOP_EP_N_RDY 5'b10010 |
|
reg [4:0] CurrState_slvGetPkt; |
reg [4:0] NextState_slvGetPkt; |
|
|
//-------------------------------------------------------------------- |
// Machine: slvGetPkt |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (RXDataIn or RXStreamStatusIn or RXByte or RXByteOldest or RXByteOld or RXDataValid or SIERxTimeOut or RXStreamStatus or getPacketEn or endPointReady or RXFifoFull or CRCError or bitStuffError or RXOverflow or RXTimeOut or ACKRxed or dataSequence or SIERxTimeOutEn or RxPID or RXPacketRdy or RXFifoWEn or RXFifoData or CurrState_slvGetPkt) |
begin : slvGetPkt_NextState |
NextState_slvGetPkt <= CurrState_slvGetPkt; |
// Set default values for outputs and signals |
next_CRCError <= CRCError; |
next_bitStuffError <= bitStuffError; |
next_RXOverflow <= RXOverflow; |
next_RXTimeOut <= RXTimeOut; |
next_ACKRxed <= ACKRxed; |
next_dataSequence <= dataSequence; |
next_SIERxTimeOutEn <= SIERxTimeOutEn; |
next_RXByte <= RXByte; |
next_RXStreamStatus <= RXStreamStatus; |
next_RxPID <= RxPID; |
next_RXPacketRdy <= RXPacketRdy; |
next_RXByteOldest <= RXByteOldest; |
next_RXByteOld <= RXByteOld; |
next_RXFifoWEn <= RXFifoWEn; |
next_RXFifoData <= RXFifoData; |
case (CurrState_slvGetPkt) |
`START_GP: |
NextState_slvGetPkt <= `WAIT_EN; |
`WAIT_PKT: |
begin |
next_CRCError <= 1'b0; |
next_bitStuffError <= 1'b0; |
next_RXOverflow <= 1'b0; |
next_RXTimeOut <= 1'b0; |
next_ACKRxed <= 1'b0; |
next_dataSequence <= 1'b0; |
next_SIERxTimeOutEn <= 1'b1; |
if (RXDataValid == 1'b1) |
begin |
NextState_slvGetPkt <= `CHK_PKT_START; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
else if (SIERxTimeOut == 1'b1) |
begin |
NextState_slvGetPkt <= `PKT_RDY; |
next_RXTimeOut <= 1'b1; |
end |
end |
`CHK_PKT_START: |
if (RXStreamStatus == `RX_PACKET_START) |
begin |
NextState_slvGetPkt <= `PROC_PKT_CHK_PID; |
next_RxPID <= RXByte[3:0]; |
end |
else |
begin |
NextState_slvGetPkt <= `PKT_RDY; |
next_RXTimeOut <= 1'b1; |
end |
`WAIT_EN: |
begin |
next_RXPacketRdy <= 1'b0; |
next_SIERxTimeOutEn <= 1'b0; |
if (getPacketEn == 1'b1) |
NextState_slvGetPkt <= `WAIT_PKT; |
end |
`PKT_RDY: |
begin |
next_RXPacketRdy <= 1'b1; |
NextState_slvGetPkt <= `WAIT_EN; |
end |
`PROC_PKT_CHK_PID: |
if (RXByte[1:0] == `HANDSHAKE) |
NextState_slvGetPkt <= `PROC_PKT_HS; |
else if (RXByte[1:0] == `DATA) |
NextState_slvGetPkt <= `PROC_PKT_DATA_W_D1; |
else |
NextState_slvGetPkt <= `PKT_RDY; |
`PROC_PKT_HS: |
if (RXDataValid == 1'b1) |
begin |
NextState_slvGetPkt <= `PKT_RDY; |
next_RXOverflow <= RXDataIn[`RX_OVERFLOW_BIT]; |
next_ACKRxed <= RXDataIn[`ACK_RXED_BIT]; |
end |
`PROC_PKT_DATA_W_D1: |
if (RXDataValid == 1'b1) |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_CHK_D1; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
`PROC_PKT_DATA_CHK_D1: |
if (RXStreamStatus == `RX_PACKET_STREAM) |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_W_D2; |
next_RXByteOldest <= RXByte; |
end |
else |
NextState_slvGetPkt <= `PROC_PKT_DATA_FIN; |
`PROC_PKT_DATA_W_D2: |
if (RXDataValid == 1'b1) |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_CHK_D2; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
`PROC_PKT_DATA_FIN: |
begin |
next_CRCError <= RXByte[`CRC_ERROR_BIT]; |
next_bitStuffError <= RXByte[`BIT_STUFF_ERROR_BIT]; |
next_dataSequence <= RXByte[`DATA_SEQUENCE_BIT]; |
NextState_slvGetPkt <= `PKT_RDY; |
end |
`PROC_PKT_DATA_CHK_D2: |
if (RXStreamStatus == `RX_PACKET_STREAM) |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_W_D3; |
next_RXByteOld <= RXByte; |
end |
else |
NextState_slvGetPkt <= `PROC_PKT_DATA_FIN; |
`PROC_PKT_DATA_W_D3: |
if (RXDataValid == 1'b1) |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_CHK_D3; |
next_RXByte <= RXDataIn; |
next_RXStreamStatus <= RXStreamStatusIn; |
end |
`PROC_PKT_DATA_CHK_D3: |
if (RXStreamStatus == `RX_PACKET_STREAM) |
NextState_slvGetPkt <= `PROC_PKT_DATA_LOOP_CHK_FIFO; |
else |
NextState_slvGetPkt <= `PROC_PKT_DATA_FIN; |
`PROC_PKT_DATA_LOOP_CHK_FIFO: |
if (endPointReady == 1'b0) |
NextState_slvGetPkt <= `PROC_PKT_DATA_LOOP_EP_N_RDY; |
else if (RXFifoFull == 1'b1) |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_LOOP_FIFO_FULL; |
next_RXOverflow <= 1'b1; |
end |
else |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_LOOP_W_D; |
next_RXFifoWEn <= 1'b1; |
next_RXFifoData <= RXByteOldest; |
next_RXByteOldest <= RXByteOld; |
next_RXByteOld <= RXByte; |
end |
`PROC_PKT_DATA_LOOP_FIFO_FULL: |
NextState_slvGetPkt <= `PROC_PKT_DATA_LOOP_W_D; |
`PROC_PKT_DATA_LOOP_W_D: |
begin |
next_RXFifoWEn <= 1'b0; |
if ((RXDataValid == 1'b1) && (RXStreamStatusIn == `RX_PACKET_STREAM)) |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_LOOP_DELAY; |
next_RXByte <= RXDataIn; |
end |
else if (RXDataValid == 1'b1) |
begin |
NextState_slvGetPkt <= `PROC_PKT_DATA_FIN; |
next_RXByte <= RXDataIn; |
end |
end |
`PROC_PKT_DATA_LOOP_DELAY: |
NextState_slvGetPkt <= `PROC_PKT_DATA_LOOP_CHK_FIFO; |
`PROC_PKT_DATA_LOOP_EP_N_RDY: // Discard data |
NextState_slvGetPkt <= `PROC_PKT_DATA_LOOP_W_D; |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : slvGetPkt_CurrentState |
if (rst) |
CurrState_slvGetPkt <= `START_GP; |
else |
CurrState_slvGetPkt <= NextState_slvGetPkt; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : slvGetPkt_RegOutput |
if (rst) |
begin |
RXByteOld <= 8'h00; |
RXByteOldest <= 8'h00; |
RXByte <= 8'h00; |
RXStreamStatus <= 8'h00; |
RXPacketRdy <= 1'b0; |
RXFifoWEn <= 1'b0; |
RXFifoData <= 8'h00; |
CRCError <= 1'b0; |
bitStuffError <= 1'b0; |
RXOverflow <= 1'b0; |
RXTimeOut <= 1'b0; |
ACKRxed <= 1'b0; |
dataSequence <= 1'b0; |
SIERxTimeOutEn <= 1'b0; |
RxPID <= 4'h0; |
end |
else |
begin |
RXByteOld <= next_RXByteOld; |
RXByteOldest <= next_RXByteOldest; |
RXByte <= next_RXByte; |
RXStreamStatus <= next_RXStreamStatus; |
RXPacketRdy <= next_RXPacketRdy; |
RXFifoWEn <= next_RXFifoWEn; |
RXFifoData <= next_RXFifoData; |
CRCError <= next_CRCError; |
bitStuffError <= next_bitStuffError; |
RXOverflow <= next_RXOverflow; |
RXTimeOut <= next_RXTimeOut; |
ACKRxed <= next_ACKRxed; |
dataSequence <= next_dataSequence; |
SIERxTimeOutEn <= next_SIERxTimeOutEn; |
RxPID <= next_RxPID; |
end |
end |
|
endmodule |
/verilog/usbhostslave/rxStatusMonitor.v
0,0 → 1,95
////////////////////////////////////////////////////////////////////// |
//// //// |
//// rxStatusMonitor.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module rxStatusMonitor(connectStateIn, connectStateOut, resumeDetectedIn, connectionEventOut, resumeIntOut, clk, rst); |
|
input [1:0] connectStateIn; |
input resumeDetectedIn; |
input clk; |
input rst; |
output connectionEventOut; |
output [1:0] connectStateOut; |
output resumeIntOut; |
|
wire [1:0] connectStateIn; |
wire resumeDetectedIn; |
reg connectionEventOut; |
reg [1:0] connectStateOut; |
reg resumeIntOut; |
wire clk; |
wire rst; |
|
reg [1:0]oldConnectState; |
reg oldResumeDetected; |
|
always @(connectStateIn) |
begin |
connectStateOut <= connectStateIn; |
end |
|
|
always @(posedge clk) |
begin |
if (rst == 1'b1) |
begin |
oldConnectState <= connectStateIn; |
oldResumeDetected <= resumeDetectedIn; |
end |
else |
begin |
oldConnectState <= connectStateIn; |
oldResumeDetected <= resumeDetectedIn; |
if (oldConnectState != connectStateIn) |
connectionEventOut <= 1'b1; |
else |
connectionEventOut <= 1'b0; |
if (resumeDetectedIn == 1'b1 && oldResumeDetected == 1'b0) |
resumeIntOut <= 1'b1; |
else |
resumeIntOut <= 1'b0; |
end |
end |
|
endmodule |
/verilog/usbhostslave/fifoRTL.v
0,0 → 1,164
////////////////////////////////////////////////////////////////////// |
//// //// |
//// fifoRTL.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// parameterized dual clock domain fifo. |
//// fifo depth is restricted to 2^ADDR_WIDTH |
//// No protection against over runs and under runs. |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module fifoRTL(wrClk, rdClk, rstSyncToWrClk, rstSyncToRdClk, dataIn, |
dataOut, fifoWEn, fifoREn, fifoFull, fifoEmpty, |
forceEmptySyncToWrClk, forceEmptySyncToRdClk, numElementsInFifo); |
//FIFO_DEPTH = ADDR_WIDTH^2. Min = 2, Max = 66536 |
parameter FIFO_WIDTH = 8; |
parameter FIFO_DEPTH = 64; |
parameter ADDR_WIDTH = 6; |
|
// Two clock domains within this module |
// These ports are within 'wrClk' domain |
input wrClk; |
input rstSyncToWrClk; |
input [FIFO_WIDTH-1:0] dataIn; |
input fifoWEn; |
input forceEmptySyncToWrClk; |
output fifoFull; |
|
// These ports are within 'rdClk' domain |
input rdClk; |
input rstSyncToRdClk; |
output [FIFO_WIDTH-1:0] dataOut; |
input fifoREn; |
input forceEmptySyncToRdClk; |
output fifoEmpty; |
output [15:0]numElementsInFifo; //note that this implies a max fifo depth of 65536 |
|
wire wrClk; |
wire rdClk; |
wire rstSyncToWrClk; |
wire rstSyncToRdClk; |
wire [FIFO_WIDTH-1:0] dataIn; |
reg [FIFO_WIDTH-1:0] dataOut; |
wire fifoWEn; |
wire fifoREn; |
reg fifoFull; |
reg fifoEmpty; |
wire forceEmpty; |
reg [15:0]numElementsInFifo; |
|
|
// local registers |
reg [ADDR_WIDTH:0]bufferInIndex; |
reg [ADDR_WIDTH:0]bufferInIndexSyncToRdClk; |
reg [ADDR_WIDTH:0]bufferOutIndex; |
reg [ADDR_WIDTH:0]bufferOutIndexSyncToWrClk; |
reg [ADDR_WIDTH-1:0]bufferInIndexToMem; |
reg [ADDR_WIDTH-1:0]bufferOutIndexToMem; |
reg [ADDR_WIDTH:0]bufferCnt; |
reg fifoREnDelayed; |
wire [FIFO_WIDTH-1:0] dataFromMem; |
|
always @(posedge wrClk) |
begin |
bufferOutIndexSyncToWrClk <= bufferOutIndex; |
if (rstSyncToWrClk == 1'b1 || forceEmptySyncToWrClk == 1'b1) |
begin |
fifoFull <= 1'b0; |
bufferInIndex <= 0; |
end |
else |
begin |
if (fifoWEn == 1'b1) begin |
bufferInIndex <= bufferInIndex + 1'b1; |
end |
if ((bufferOutIndexSyncToWrClk[ADDR_WIDTH-1:0] == bufferInIndex[ADDR_WIDTH-1:0]) && |
(bufferOutIndexSyncToWrClk[ADDR_WIDTH] != bufferInIndex[ADDR_WIDTH]) ) |
fifoFull <= 1'b1; |
else |
fifoFull <= 1'b0; |
end |
end |
|
always @(bufferInIndexSyncToRdClk or bufferOutIndex) |
bufferCnt <= bufferInIndexSyncToRdClk - bufferOutIndex; |
|
always @(posedge rdClk) |
begin |
numElementsInFifo <= { {16-ADDR_WIDTH+1{1'b0}}, bufferCnt }; //pad bufferCnt with leading zeroes |
bufferInIndexSyncToRdClk <= bufferInIndex; |
if (rstSyncToRdClk == 1'b1 || forceEmptySyncToRdClk == 1'b1) |
begin |
fifoEmpty <= 1'b1; |
bufferOutIndex <= 0; |
fifoREnDelayed <= 1'b0; |
end |
else |
begin |
fifoREnDelayed <= fifoREn; |
if (fifoREn == 1'b1 && fifoREnDelayed == 1'b0) begin |
dataOut <= dataFromMem; |
bufferOutIndex <= bufferOutIndex + 1'b1; |
end |
if (bufferInIndexSyncToRdClk == bufferOutIndex) |
fifoEmpty <= 1'b1; |
else |
fifoEmpty <= 1'b0; |
end |
end |
|
|
always @(bufferInIndex or bufferOutIndex) begin |
bufferInIndexToMem <= bufferInIndex[ADDR_WIDTH-1:0]; |
bufferOutIndexToMem <= bufferOutIndex[ADDR_WIDTH-1:0]; |
end |
|
dpMem_dc #(FIFO_WIDTH, FIFO_DEPTH, ADDR_WIDTH) u_dpMem_dc ( |
.addrIn(bufferInIndexToMem), |
.addrOut(bufferOutIndexToMem), |
.wrClk(wrClk), |
.rdClk(rdClk), |
.dataIn(dataIn), |
.writeEn(fifoWEn), |
.readEn(fifoREn), |
.dataOut(dataFromMem)); |
|
endmodule |
/verilog/usbhostslave/SIEReceiver.v
0,0 → 1,283
|
// File : ../RTL/serialInterfaceEngine/siereceiver.v |
// Generated : 11/10/06 05:37:23 |
// From : ../RTL/serialInterfaceEngine/siereceiver.asf |
// By : FSM2VHDL ver. 5.0.0.9 |
|
////////////////////////////////////////////////////////////////////// |
//// //// |
//// SIEReceiver |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// http://www.opencores.org/cores/usbhostslave/ //// |
//// //// |
//// Module Description: //// |
//// |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
`include "usbhostslave_serialinterfaceengine_h.v" |
|
|
module SIEReceiver (RxWireDataIn, RxWireDataWEn, clk, connectState, rst); |
input [1:0] RxWireDataIn; |
input RxWireDataWEn; |
input clk; |
input rst; |
output [1:0] connectState; |
|
wire [1:0] RxWireDataIn; |
wire RxWireDataWEn; |
wire clk; |
reg [1:0] connectState, next_connectState; |
wire rst; |
|
// diagram signals declarations |
reg [3:0]RXStMachCurrState, next_RXStMachCurrState; |
reg [7:0]RXWaitCount, next_RXWaitCount; |
reg [1:0]RxBits, next_RxBits; |
|
// BINARY ENCODED state machine: rcvr |
// State codes definitions: |
`define WAIT_FS_CONN_CHK_RX_BITS 4'b0000 |
`define WAIT_LS_CONN_CHK_RX_BITS 4'b0001 |
`define LS_CONN_CHK_RX_BITS 4'b0010 |
`define DISCNCT_CHK_RXBITS 4'b0011 |
`define WAIT_BIT 4'b0100 |
`define START_SRX 4'b0101 |
`define FS_CONN_CHK_RX_BITS1 4'b0110 |
`define WAIT_LS_DIS_CHK_RX_BITS 4'b0111 |
`define WAIT_FS_DIS_CHK_RX_BITS2 4'b1000 |
|
reg [3:0] CurrState_rcvr; |
reg [3:0] NextState_rcvr; |
|
|
//-------------------------------------------------------------------- |
// Machine: rcvr |
//-------------------------------------------------------------------- |
//---------------------------------- |
// Next State Logic (combinatorial) |
//---------------------------------- |
always @ (RxWireDataIn or RxBits or RXWaitCount or RxWireDataWEn or RXStMachCurrState or connectState or CurrState_rcvr) |
begin : rcvr_NextState |
NextState_rcvr <= CurrState_rcvr; |
// Set default values for outputs and signals |
next_RxBits <= RxBits; |
next_RXStMachCurrState <= RXStMachCurrState; |
next_RXWaitCount <= RXWaitCount; |
next_connectState <= connectState; |
case (CurrState_rcvr) |
`WAIT_BIT: |
if ((RxWireDataWEn == 1'b1) && (RXStMachCurrState == `WAIT_LOW_SPEED_CONN_ST)) |
begin |
NextState_rcvr <= `WAIT_LS_CONN_CHK_RX_BITS; |
next_RxBits <= RxWireDataIn; |
end |
else if ((RxWireDataWEn == 1'b1) && (RXStMachCurrState == `CONNECT_LOW_SPEED_ST)) |
begin |
NextState_rcvr <= `LS_CONN_CHK_RX_BITS; |
next_RxBits <= RxWireDataIn; |
end |
else if ((RxWireDataWEn == 1'b1) && (RXStMachCurrState == `CONNECT_FULL_SPEED_ST)) |
begin |
NextState_rcvr <= `FS_CONN_CHK_RX_BITS1; |
next_RxBits <= RxWireDataIn; |
end |
else if ((RxWireDataWEn == 1'b1) && (RXStMachCurrState == `WAIT_LOW_SP_DISCONNECT_ST)) |
begin |
NextState_rcvr <= `WAIT_LS_DIS_CHK_RX_BITS; |
next_RxBits <= RxWireDataIn; |
end |
else if ((RxWireDataWEn == 1'b1) && (RXStMachCurrState == `WAIT_FULL_SP_DISCONNECT_ST)) |
begin |
NextState_rcvr <= `WAIT_FS_DIS_CHK_RX_BITS2; |
next_RxBits <= RxWireDataIn; |
end |
else if ((RxWireDataWEn == 1'b1) && (RXStMachCurrState == `DISCONNECT_ST)) |
begin |
NextState_rcvr <= `DISCNCT_CHK_RXBITS; |
next_RxBits <= RxWireDataIn; |
end |
else if ((RxWireDataWEn == 1'b1) && (RXStMachCurrState == `WAIT_FULL_SPEED_CONN_ST)) |
begin |
NextState_rcvr <= `WAIT_FS_CONN_CHK_RX_BITS; |
next_RxBits <= RxWireDataIn; |
end |
`START_SRX: |
begin |
next_RXStMachCurrState <= `DISCONNECT_ST; |
next_RXWaitCount <= 8'h00; |
next_connectState <= `DISCONNECT; |
next_RxBits <= 2'b00; |
NextState_rcvr <= `WAIT_BIT; |
end |
`DISCNCT_CHK_RXBITS: |
if (RxBits == `ZERO_ONE) |
begin |
NextState_rcvr <= `WAIT_BIT; |
next_RXStMachCurrState <= `WAIT_LOW_SPEED_CONN_ST; |
next_RXWaitCount <= 8'h00; |
end |
else if (RxBits == `ONE_ZERO) |
begin |
NextState_rcvr <= `WAIT_BIT; |
next_RXStMachCurrState <= `WAIT_FULL_SPEED_CONN_ST; |
next_RXWaitCount <= 8'h00; |
end |
else |
NextState_rcvr <= `WAIT_BIT; |
`WAIT_FS_CONN_CHK_RX_BITS: |
begin |
if (RxBits == `ONE_ZERO) |
begin |
next_RXWaitCount <= RXWaitCount + 1'b1; |
if (RXWaitCount == `CONNECT_WAIT_TIME) |
begin |
next_connectState <= `FULL_SPEED_CONNECT; |
next_RXStMachCurrState <= `CONNECT_FULL_SPEED_ST; |
end |
end |
else |
begin |
next_RXStMachCurrState <= `DISCONNECT_ST; |
end |
NextState_rcvr <= `WAIT_BIT; |
end |
`WAIT_LS_CONN_CHK_RX_BITS: |
begin |
if (RxBits == `ZERO_ONE) |
begin |
next_RXWaitCount <= RXWaitCount + 1'b1; |
if (RXWaitCount == `CONNECT_WAIT_TIME) |
begin |
next_connectState <= `LOW_SPEED_CONNECT; |
next_RXStMachCurrState <= `CONNECT_LOW_SPEED_ST; |
end |
end |
else |
begin |
next_RXStMachCurrState <= `DISCONNECT_ST; |
end |
NextState_rcvr <= `WAIT_BIT; |
end |
`LS_CONN_CHK_RX_BITS: |
begin |
NextState_rcvr <= `WAIT_BIT; |
if (RxBits == `SE0) |
begin |
next_RXStMachCurrState <= `WAIT_LOW_SP_DISCONNECT_ST; |
next_RXWaitCount <= 0; |
end |
end |
`FS_CONN_CHK_RX_BITS1: |
begin |
NextState_rcvr <= `WAIT_BIT; |
if (RxBits == `SE0) |
begin |
next_RXStMachCurrState <= `WAIT_FULL_SP_DISCONNECT_ST; |
next_RXWaitCount <= 0; |
end |
end |
`WAIT_LS_DIS_CHK_RX_BITS: |
begin |
NextState_rcvr <= `WAIT_BIT; |
if (RxBits == `SE0) |
begin |
next_RXWaitCount <= RXWaitCount + 1'b1; |
if (RXWaitCount == `DISCONNECT_WAIT_TIME) |
begin |
next_RXStMachCurrState <= `DISCONNECT_ST; |
next_connectState <= `DISCONNECT; |
end |
end |
else |
begin |
next_RXStMachCurrState <= `CONNECT_LOW_SPEED_ST; |
end |
end |
`WAIT_FS_DIS_CHK_RX_BITS2: |
begin |
NextState_rcvr <= `WAIT_BIT; |
if (RxBits == `SE0) |
begin |
next_RXWaitCount <= RXWaitCount + 1'b1; |
if (RXWaitCount == `DISCONNECT_WAIT_TIME) |
begin |
next_RXStMachCurrState <= `DISCONNECT_ST; |
next_connectState <= `DISCONNECT; |
end |
end |
else |
begin |
next_RXStMachCurrState <= `CONNECT_FULL_SPEED_ST; |
end |
end |
endcase |
end |
|
//---------------------------------- |
// Current State Logic (sequential) |
//---------------------------------- |
always @ (posedge clk) |
begin : rcvr_CurrentState |
if (rst) |
CurrState_rcvr <= `START_SRX; |
else |
CurrState_rcvr <= NextState_rcvr; |
end |
|
//---------------------------------- |
// Registered outputs logic |
//---------------------------------- |
always @ (posedge clk) |
begin : rcvr_RegOutput |
if (rst) |
begin |
RXStMachCurrState <= `DISCONNECT_ST; |
RXWaitCount <= 8'h00; |
RxBits <= 2'b00; |
connectState <= `DISCONNECT; |
end |
else |
begin |
RXStMachCurrState <= next_RXStMachCurrState; |
RXWaitCount <= next_RXWaitCount; |
RxBits <= next_RxBits; |
connectState <= next_connectState; |
end |
end |
|
endmodule |
/verilog/usbhostslave/dpMem_dc.v
0,0 → 1,107
////////////////////////////////////////////////////////////////////// |
//// //// |
//// dpMem_dc.v //// |
//// //// |
//// This file is part of the usbhostslave opencores effort. |
//// <http://www.opencores.org/cores//> //// |
//// //// |
//// Module Description: //// |
//// Synchronous dual port memory with dual clocks |
//// //// |
//// To Do: //// |
//// |
//// //// |
//// Author(s): //// |
//// - Steve Fielding, sfielding@base2designs.com //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from <http://www.opencores.org/lgpl.shtml> //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
`include "timescale.v" |
|
module dpMem_dc( addrIn, addrOut, wrClk, rdClk, dataIn, writeEn, readEn, dataOut); |
//FIFO_DEPTH = ADDR_WIDTH^2 |
parameter FIFO_WIDTH = 8; |
parameter FIFO_DEPTH = 64; |
parameter ADDR_WIDTH = 6; |
|
input wrClk; |
input rdClk; |
input [FIFO_WIDTH-1:0] dataIn; |
output [FIFO_WIDTH-1:0] dataOut; |
input writeEn; |
input readEn; |
input [ADDR_WIDTH-1:0] addrIn; |
input [ADDR_WIDTH-1:0] addrOut; |
|
wire wrClk; |
wire rdClk; |
wire [FIFO_WIDTH-1:0] dataIn; |
//reg [FIFO_WIDTH-1:0] dataOut; |
wire [FIFO_WIDTH-1:0] dataOut; |
wire writeEn; |
wire readEn; |
wire [ADDR_WIDTH-1:0] addrIn; |
wire [ADDR_WIDTH-1:0] addrOut; |
|
// Added no_rw_check on this -- Julius |
reg [FIFO_WIDTH-1:0] buffer [0:FIFO_DEPTH-1] /*synthesis syn_ramstyle = "no_rw_check"*/; |
|
// Modifying this to ensure this is inferred as a block RAM |
|
// Register address |
reg [ADDR_WIDTH-1:0] addrOut_r; |
|
always @(posedge rdClk) |
//not sure if we should have this enable here: |
// if (readEn) |
addrOut_r <= addrOut; |
|
assign dataOut = buffer[addrOut_r]; |
|
// synchronous write |
always @(posedge wrClk) begin |
if (writeEn == 1'b1) |
buffer[addrIn] <= dataIn; |
end |
|
/* |
// synchronous read. Introduces one clock cycle delay |
|
always @(posedge rdClk) begin |
dataOut <= buffer[addrOut]; |
end |
|
|
// synchronous write |
always @(posedge wrClk) begin |
if (writeEn == 1'b1) |
buffer[addrIn] <= dataIn; |
end |
*/ |
|
endmodule |
/verilog/i2c_master_slave/i2c_master_byte_ctrl.v
0,0 → 1,509
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE rev.B2 compliant I2C Master byte-controller //// |
//// //// |
//// //// |
//// Author: Richard Herveille //// |
//// richard@asics.ws //// |
//// www.asics.ws //// |
//// //// |
//// Downloaded from: http://www.opencores.org/projects/i2c/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Richard Herveille //// |
//// richard@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: i2c_master_byte_ctrl.v,v 1.8 2009-01-19 20:29:26 rherveille Exp $ |
// |
// $Date: 2009-01-19 20:29:26 $ |
// $Revision: 1.8 $ |
// $Author: rherveille $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.7 2004/02/18 11:40:46 rherveille |
// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command. |
// |
// Revision 1.6 2003/08/09 07:01:33 rherveille |
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. |
// Fixed a potential bug in the byte controller's host-acknowledge generation. |
// |
// Revision 1.5 2002/12/26 15:02:32 rherveille |
// Core is now a Multimaster I2C controller |
// |
// Revision 1.4 2002/11/30 22:24:40 rherveille |
// Cleaned up code |
// |
// Revision 1.3 2001/11/05 11:59:25 rherveille |
// Fixed wb_ack_o generation bug. |
// Fixed bug in the byte_controller statemachine. |
// Added headers. |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
`include "i2c_master_slave_defines.v" |
|
module i2c_master_byte_ctrl |
( |
clk, my_addr, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, |
din, cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, sl_cont, scl_o, |
scl_oen, sda_i, sda_o, sda_oen,slave_dat_req, slave_en, slave_dat_avail, |
slave_act, slave_cmd_ack |
); |
|
|
// |
// inputs & outputs |
// |
input clk; // master clock |
input my_addr; // Slave address input |
input rst; // synchronous active high reset |
input nReset; // asynchronous active low reset |
input ena; // core enable signal |
input sl_cont; |
input [15:0] clk_cnt; // 4x SCL |
|
// control inputs |
input start; |
input stop; |
input read; |
input write; |
input ack_in; |
input [7:0] din; |
|
// status outputs |
output cmd_ack; |
reg cmd_ack; |
output ack_out; |
reg ack_out; |
output i2c_busy; |
output i2c_al; |
output [7:0] dout; |
|
// I2C signals |
input scl_i; |
output scl_o; |
output scl_oen; |
input sda_i; |
output sda_o; |
output sda_oen; |
input slave_en; |
output reg slave_dat_req; |
output reg slave_dat_avail; |
output reg slave_act; |
output reg slave_cmd_ack; |
// |
// Variable declarations |
// |
|
// statemachine |
parameter [9:0] ST_IDLE = 10'b00_0000_0000; |
parameter [9:0] ST_START = 10'b00_0000_0001; |
parameter [9:0] ST_READ = 10'b00_0000_0010; |
parameter [9:0] ST_WRITE = 10'b00_0000_0100; |
parameter [9:0] ST_ACK = 10'b00_0000_1000; |
parameter [9:0] ST_STOP = 10'b00_0001_0000; |
parameter [9:0] ST_SL_ACK = 10'b00_0010_0000; |
parameter [9:0] ST_SL_RD = 10'b00_0100_0000; |
parameter [9:0] ST_SL_WR = 10'b00_1000_0000; |
parameter [9:0] ST_SL_WAIT = 10'b01_0000_0000; |
parameter [9:0] ST_SL_PRELOAD = 10'b10_0000_0000; |
|
|
reg sl_wait; |
// signals for bit_controller |
wire [6:0] my_addr; |
reg [3:0] core_cmd; |
reg core_txd; |
wire core_ack, core_rxd; |
wire sl_cont; |
// signals for shift register |
reg [7:0] sr; //8bit shift register |
reg shift, ld; |
reg master_mode; |
reg [1:0] slave_cmd_out; |
// signals for state machine |
wire go; |
reg [2:0] dcnt; |
wire cnt_done; |
wire slave_ack; |
|
|
//Slave signals |
wire slave_adr_received; |
wire [7:0] slave_adr; |
|
|
reg [1:0] slave_cmd; |
// |
// Module body |
// |
|
// hookup bit_controller |
i2c_master_bit_ctrl bit_controller |
( |
.clk ( clk ), |
.rst ( rst ), |
.nReset ( nReset ), |
.ena ( ena ), |
.clk_cnt ( clk_cnt ), |
.cmd ( core_cmd ), |
.cmd_ack ( core_ack ), |
.busy ( i2c_busy ), |
.al ( i2c_al ), |
.din ( core_txd ), |
.dout ( core_rxd ), |
.scl_i ( scl_i ), |
.scl_o ( scl_o ), |
.scl_oen ( scl_oen ), |
.sda_i ( sda_i ), |
.sda_o ( sda_o ), |
.sda_oen ( sda_oen ), |
.slave_adr_received ( slave_adr_received ), |
.slave_adr ( slave_adr ), |
.master_mode (master_mode), |
.cmd_slave_ack (slave_ack), |
.slave_cmd (slave_cmd_out), |
.sl_wait (sl_wait), |
.slave_reset (slave_reset) |
); |
|
reg slave_adr_received_d; |
// generate go-signal |
assign go = (read | write | stop) & ~cmd_ack; |
|
// assign dout output to shift-register |
assign dout = sr; |
|
always @(posedge clk or negedge nReset) |
if (!nReset) |
slave_adr_received_d <= 1'b0; |
else |
slave_adr_received_d <= slave_adr_received; |
|
// generate shift register |
always @(posedge clk or negedge nReset) |
if (!nReset) |
sr <= 8'h0; |
else if (rst) |
sr <= 8'h0; |
else if (ld) |
sr <= din; |
else if (shift) |
sr <= {sr[6:0], core_rxd}; |
else if (slave_adr_received_d & slave_act) |
sr <= {slave_adr[7:1], 1'b0}; |
|
|
|
// generate counter |
always @(posedge clk or negedge nReset) |
if (!nReset) |
dcnt <= 3'h0; |
else if (rst) |
dcnt <= 3'h0; |
else if (ld) |
dcnt <= 3'h7; |
|
else if (shift) |
dcnt <= dcnt - 3'h1; |
|
assign cnt_done = ~(|dcnt); |
|
// |
// state machine |
// |
reg [9:0] c_state; // synopsys enum_state |
|
|
|
always @(posedge clk or negedge nReset) |
if (!nReset) |
begin |
sl_wait <= 1'b0; |
core_cmd <= `I2C_CMD_NOP; |
core_txd <= 1'b0; |
shift <= 1'b0; |
ld <= 1'b0; |
cmd_ack <= 1'b0; |
c_state <= ST_IDLE; |
ack_out <= 1'b0; |
master_mode <= 1'b0; |
slave_cmd <= 2'b0; |
slave_dat_req <= 1'b0; |
slave_dat_avail <= 1'b0; |
slave_act <= 1'b0; |
slave_cmd_out <= 2'b0; |
slave_cmd_ack <= 1'b0; |
end |
else if (rst | i2c_al | slave_reset) |
begin |
core_cmd <= `I2C_CMD_NOP; |
core_txd <= 1'b0; |
shift <= 1'b0; |
sl_wait <= 1'b0; |
ld <= 1'b0; |
cmd_ack <= 1'b0; |
c_state <= ST_IDLE; |
ack_out <= 1'b0; |
master_mode <= 1'b0; |
slave_cmd <= 2'b0; |
slave_cmd_out <= 2'b0; |
slave_dat_req <= 1'b0; |
slave_dat_avail <= 1'b0; |
slave_act <= 1'b0; |
slave_cmd_ack <= 1'b0; |
end |
else |
begin |
slave_cmd_out <= slave_cmd; |
// initially reset all signals |
core_txd <= sr[7]; |
shift <= 1'b0; |
ld <= 1'b0; |
cmd_ack <= 1'b0; |
slave_cmd_ack <= 1'b0; |
|
case (c_state) // synopsys full_case parallel_case |
ST_IDLE: |
begin |
slave_act <= 1'b0; |
if (slave_en & slave_adr_received & |
(slave_adr[7:1] == my_addr )) begin |
|
c_state <= ST_SL_ACK; |
master_mode <= 1'b0; |
slave_act <= 1'b1; |
slave_cmd <= `I2C_SLAVE_CMD_WRITE; |
core_txd <= 1'b0; |
|
end |
else if (go && !slave_act ) |
begin |
if (start ) |
begin |
c_state <= ST_START; |
core_cmd <= `I2C_CMD_START; |
master_mode <= 1'b1; |
end |
else if (read) |
begin |
c_state <= ST_READ; |
core_cmd <= `I2C_CMD_READ; |
end |
else if (write) |
begin |
c_state <= ST_WRITE; |
core_cmd <= `I2C_CMD_WRITE; |
end |
else // stop |
begin |
c_state <= ST_STOP; |
core_cmd <= `I2C_CMD_STOP; |
|
end |
|
ld <= 1'b1; |
end |
|
end |
ST_SL_RD: //If master read, slave sending data |
begin |
slave_cmd <= `I2C_SLAVE_CMD_NOP; |
if (slave_ack) begin |
if (cnt_done) begin |
c_state <= ST_SL_ACK; |
slave_cmd <= `I2C_SLAVE_CMD_READ; |
end |
else |
begin |
c_state <= ST_SL_RD; |
slave_cmd <= `I2C_SLAVE_CMD_WRITE; |
shift <= 1'b1; |
end |
end |
end |
ST_SL_WR: //If master write, slave reading data |
begin |
slave_cmd <= `I2C_SLAVE_CMD_NOP; |
if (slave_ack) |
begin |
if (cnt_done) |
begin |
c_state <= ST_SL_ACK; |
slave_cmd <= `I2C_SLAVE_CMD_WRITE; |
core_txd <= 1'b0; |
end |
else |
begin |
c_state <= ST_SL_WR; |
slave_cmd <= `I2C_SLAVE_CMD_READ; |
end |
shift <= 1'b1; |
end |
end |
ST_SL_WAIT: //Wait for interupt-clear and hold SCL in waitstate |
begin |
sl_wait <= 1'b1; |
if (sl_cont) begin |
sl_wait <= 1'b0; |
ld <= 1'b1; |
slave_dat_req <= 1'b0; |
slave_dat_avail <= 1'b0; |
c_state <= ST_SL_PRELOAD; |
end |
end |
|
ST_SL_PRELOAD: |
if (slave_adr[0]) begin |
c_state <= ST_SL_RD; |
slave_cmd <= `I2C_SLAVE_CMD_WRITE; |
end |
else begin |
c_state <= ST_SL_WR; |
slave_cmd <= `I2C_SLAVE_CMD_READ; |
end |
|
ST_SL_ACK: |
begin |
slave_cmd <= `I2C_SLAVE_CMD_NOP; |
if (slave_ack) begin |
ack_out <= core_rxd; |
slave_cmd_ack <= 1'b1; |
if (!core_rxd) begin // Valid ack recived |
// generate slave command acknowledge signal if |
// succesful transfer |
c_state <= ST_SL_WAIT; |
if (slave_adr[0]) begin // I2C read request |
slave_dat_req <= 1'b1; |
end |
else begin // I2C write request |
slave_dat_avail <= 1'b1; |
end |
end |
else begin |
c_state <= ST_IDLE; |
end |
end |
else begin |
core_txd <= 1'b0; |
end |
end |
|
ST_START: |
if (core_ack) |
begin |
if (read) |
begin |
c_state <= ST_READ; |
core_cmd <= `I2C_CMD_READ; |
end |
else |
begin |
c_state <= ST_WRITE; |
core_cmd <= `I2C_CMD_WRITE; |
end |
|
ld <= 1'b1; |
end |
|
ST_WRITE: |
if (core_ack) |
if (cnt_done) |
begin |
c_state <= ST_ACK; |
core_cmd <= `I2C_CMD_READ; |
end |
else |
begin |
c_state <= ST_WRITE; // stay in same state |
core_cmd <= `I2C_CMD_WRITE; // write next bit |
shift <= 1'b1; |
end |
|
ST_READ: |
if (core_ack) |
begin |
if (cnt_done) |
begin |
c_state <= ST_ACK; |
core_cmd <= `I2C_CMD_WRITE; |
end |
else |
begin |
c_state <= ST_READ; // stay in same state |
core_cmd <= `I2C_CMD_READ; // read next bit |
end |
|
shift <= 1'b1; |
core_txd <= ack_in; |
end |
|
ST_ACK: |
if (core_ack) |
begin |
if (stop) |
begin |
c_state <= ST_STOP; |
core_cmd <= `I2C_CMD_STOP; |
end |
else |
begin |
c_state <= ST_IDLE; |
core_cmd <= `I2C_CMD_NOP; |
|
// generate command acknowledge signal |
cmd_ack <= 1'b1; |
end |
|
// assign ack_out output to bit_controller_rxd (contains |
// last received bit) |
ack_out <= core_rxd; |
|
core_txd <= 1'b1; |
end |
else |
core_txd <= ack_in; |
|
ST_STOP: |
if (core_ack) |
begin |
c_state <= ST_IDLE; |
core_cmd <= `I2C_CMD_NOP; |
|
// generate command acknowledge signal |
cmd_ack <= 1'b1; |
end |
|
endcase |
end |
endmodule |
/verilog/i2c_master_slave/i2c_master_slave.v
0,0 → 1,334
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE revB.2 compliant I2C Master controller Top-level //// |
//// //// |
//// //// |
//// Author: Richard Herveille //// |
//// richard@asics.ws //// |
//// www.asics.ws //// |
//// //// |
//// Downloaded from: http://www.opencores.org/projects/i2c/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Richard Herveille //// |
//// richard@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: i2c_master_top.v,v 1.12 2009-01-19 20:29:26 rherveille Exp $ |
// |
// $Date: 2009-01-19 20:29:26 $ |
// $Revision: 1.12 $ |
// $Author: rherveille $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// Revision 1.11 2005/02/27 09:26:24 rherveille |
// Fixed register overwrite issue. |
// Removed full_case pragma, replaced it by a default statement. |
// |
// Revision 1.10 2003/09/01 10:34:38 rherveille |
// Fix a blocking vs. non-blocking error in the wb_dat output mux. |
// |
// Revision 1.9 2003/01/09 16:44:45 rherveille |
// Fixed a bug in the Command Register declaration. |
// |
// Revision 1.8 2002/12/26 16:05:12 rherveille |
// Small code simplifications |
// |
// Revision 1.7 2002/12/26 15:02:32 rherveille |
// Core is now a Multimaster I2C controller |
// |
// Revision 1.6 2002/11/30 22:24:40 rherveille |
// Cleaned up code |
// |
// Revision 1.5 2001/11/10 10:52:55 rherveille |
// Changed PRER reset value from 0x0000 to 0xffff, conform specs. |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
`include "i2c_master_slave_defines.v" |
|
//module i2c_master_top( |
module i2c_master_slave |
( |
wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o, |
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o, |
scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o ); |
|
// parameters |
parameter ARST_LVL = 1'b1; // asynchronous reset level |
parameter [6:0] DEFAULT_SLAVE_ADDR = 7'b111_1110; |
// |
// inputs & outputs |
// |
|
// wishbone signals |
input wb_clk_i; // master clock input |
input wb_rst_i; // synchronous active high reset |
input arst_i; // asynchronous reset |
input [2:0] wb_adr_i; // lower address bits |
input [7:0] wb_dat_i; // databus input |
output [7:0] wb_dat_o; // databus output |
input wb_we_i; // write enable input |
input wb_stb_i; // stobe/core select signal |
input wb_cyc_i; // valid bus cycle input |
output wb_ack_o; // bus cycle acknowledge output |
output wb_inta_o; // interrupt request signal output |
|
reg [7:0] wb_dat_o; |
reg wb_ack_o; |
reg wb_inta_o; |
|
// I2C signals |
// i2c clock line |
input scl_pad_i; // SCL-line input |
output scl_pad_o; // SCL-line output (always 1'b0) |
output scl_padoen_o; // SCL-line output enable (active low) |
|
// i2c data line |
input sda_pad_i; // SDA-line input |
output sda_pad_o; // SDA-line output (always 1'b0) |
output sda_padoen_o; // SDA-line output enable (active low) |
|
|
// |
// variable declarations |
// |
|
// registers |
reg [15:0] prer; // clock prescale register |
reg [ 7:0] ctr; // control register |
reg [ 7:0] txr; // transmit register |
wire [ 7:0] rxr; // receive register |
reg [ 7:0] cr; // command register |
wire [ 7:0] sr; // status register |
reg [ 6:0] sladr; // slave address register |
|
// done signal: command completed, clear command register |
wire done; |
wire slave_done; |
// core enable signal |
wire core_en; |
wire ien; |
wire slave_en; |
|
// status register signals |
wire irxack; |
reg rxack; // received aknowledge from slave |
reg tip; // transfer in progress |
reg irq_flag; // interrupt pending flag |
wire i2c_busy; // bus busy (start signal detected) |
wire i2c_al; // i2c bus arbitration lost |
reg al; // status register arbitration lost bit |
reg slave_mode; |
// |
// module body |
// |
wire slave_act; |
// generate internal reset |
wire rst_i = arst_i ^ ARST_LVL; |
|
// generate wishbone signals |
wire wb_wacc = wb_we_i & wb_ack_o; |
|
// generate acknowledge output signal ... |
always @(posedge wb_clk_i) |
// ... because timing is always honored. |
wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o; |
|
// assign DAT_O |
always @(posedge wb_clk_i) |
begin |
case (wb_adr_i) // synopsys parallel_case |
3'b000: wb_dat_o <= prer[ 7:0]; |
3'b001: wb_dat_o <= prer[15:8]; |
3'b010: wb_dat_o <= ctr; |
3'b011: wb_dat_o <= rxr; // write is transmit register (txr) |
3'b100: wb_dat_o <= sr; // write is command register (cr) |
3'b101: wb_dat_o <= txr; // Debug out of TXR |
3'b110: wb_dat_o <= cr; // Debug out control reg |
3'b111: wb_dat_o <= {1'b0,sladr}; // slave address register |
endcase |
end |
|
// generate registers |
always @(posedge wb_clk_i or negedge rst_i) |
if (!rst_i) |
begin |
prer <= 16'hffff; |
ctr <= 8'h0; |
txr <= 8'h0; |
sladr <= DEFAULT_SLAVE_ADDR; |
end |
else if (wb_rst_i) |
begin |
prer <= 16'hffff; |
ctr <= 8'h0; |
txr <= 8'h0; |
sladr <= DEFAULT_SLAVE_ADDR; |
end |
else |
if (wb_wacc) |
case (wb_adr_i) // synopsys parallel_case |
3'b000 : prer [ 7:0] <= wb_dat_i; |
3'b001 : prer [15:8] <= wb_dat_i; |
3'b010 : ctr <= wb_dat_i; |
3'b011 : txr <= wb_dat_i; |
3'b111 : sladr <= wb_dat_i[6:0]; |
default: ; |
endcase |
|
// generate command register (special case) |
always @(posedge wb_clk_i or negedge rst_i) |
if (!rst_i) |
cr <= 8'h0; |
else if (wb_rst_i) |
cr <= 8'h0; |
else if (wb_wacc) |
begin |
if (core_en & (wb_adr_i == 3'b100) ) |
cr <= wb_dat_i; |
end |
else |
begin |
cr[1] <= 1'b0; |
if (done | i2c_al) |
cr[7:4] <= 4'h0; // clear command bits when done |
// or when aribitration lost |
cr[2] <= 1'b0; // reserved bits |
cr[0] <= 1'b0; // clear IRQ_ACK bit |
|
|
|
end |
|
|
// decode command register |
wire sta = cr[7]; |
wire sto = cr[6]; |
wire rd = cr[5]; |
wire wr = cr[4]; |
wire ack = cr[3]; |
wire sl_cont = cr[1]; |
wire iack = cr[0]; |
|
// decode control register |
assign core_en = ctr[7]; |
assign ien = ctr[6]; |
assign slave_en = ctr[5]; |
|
|
// hookup byte controller block |
i2c_master_byte_ctrl byte_controller |
( |
.clk ( wb_clk_i ), |
.my_addr ( sladr ), |
.rst ( wb_rst_i ), |
.nReset ( rst_i ), |
.ena ( core_en ), |
.clk_cnt ( prer ), |
.start ( sta ), |
.stop ( sto ), |
.read ( rd ), |
.write ( wr ), |
.ack_in ( ack ), |
.din ( txr ), |
.cmd_ack ( done ), |
.ack_out ( irxack ), |
.dout ( rxr ), |
.i2c_busy ( i2c_busy ), |
.i2c_al ( i2c_al ), |
.scl_i ( scl_pad_i ), |
.scl_o ( scl_pad_o ), |
.scl_oen ( scl_padoen_o ), |
.sda_i ( sda_pad_i ), |
.sda_o ( sda_pad_o ), |
.sda_oen ( sda_padoen_o ), |
.sl_cont ( sl_cont ), |
.slave_en ( slave_en ), |
.slave_dat_req (slave_dat_req), |
.slave_dat_avail (slave_dat_avail), |
.slave_act (slave_act), |
.slave_cmd_ack (slave_done) |
); |
|
// status register block + interrupt request signal |
always @(posedge wb_clk_i or negedge rst_i) |
if (!rst_i) |
begin |
al <= 1'b0; |
rxack <= 1'b0; |
tip <= 1'b0; |
irq_flag <= 1'b0; |
slave_mode <= 1'b0; |
end |
else if (wb_rst_i) |
begin |
al <= 1'b0; |
rxack <= 1'b0; |
tip <= 1'b0; |
irq_flag <= 1'b0; |
slave_mode <= 1'b0; |
end |
else |
begin |
al <= i2c_al | (al & ~sta); |
rxack <= irxack; |
tip <= (rd | wr); |
// interrupt request flag is always generated |
irq_flag <= (done | slave_done| i2c_al | slave_dat_req | |
slave_dat_avail | irq_flag) & ~iack; |
if (done) |
slave_mode <= slave_act; |
|
end |
|
// generate interrupt request signals |
always @(posedge wb_clk_i or negedge rst_i) |
if (!rst_i) |
wb_inta_o <= 1'b0; |
else if (wb_rst_i) |
wb_inta_o <= 1'b0; |
else |
// interrupt signal is only generated when IEN (interrupt enable bit |
// is set) |
wb_inta_o <= irq_flag && ien; |
|
// assign status register bits |
assign sr[7] = rxack; |
assign sr[6] = i2c_busy; |
assign sr[5] = al; |
assign sr[4] = slave_mode; // reserved |
assign sr[3] = slave_dat_avail; |
assign sr[2] = slave_dat_req; |
assign sr[1] = tip; |
assign sr[0] = irq_flag; |
|
endmodule |
/verilog/i2c_master_slave/README
0,0 → 1,6
i2c master and slave |
|
This core is based on the i2c master by Richard Herveille from OpenCores.org, |
with added slave capability by ORSoC. See the driver software in sw/drivers |
for details on use of the core. |
|
/verilog/i2c_master_slave/i2c_master_bit_ctrl.v
0,0 → 1,730
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE rev.B2 compliant I2C Master bit-controller //// |
//// //// |
//// //// |
//// Author: Richard Herveille //// |
//// richard@asics.ws //// |
//// www.asics.ws //// |
//// //// |
//// Downloaded from: http://www.opencores.org/projects/i2c/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Richard Herveille //// |
//// richard@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: i2c_master_bit_ctrl.v,v 1.14 2009-01-20 10:25:29 rherveille Exp $ |
// |
// $Date: 2009-01-20 10:25:29 $ |
// $Revision: 1.14 $ |
// $Author: rherveille $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: $ |
// Revision 1.14 2009/01/20 10:25:29 rherveille |
// Added clock synchronization logic |
// Fixed slave_wait signal |
// |
// Revision 1.13 2009/01/19 20:29:26 rherveille |
// Fixed synopsys miss spell (synopsis) |
// Fixed cr[0] register width |
// Fixed ! usage instead of ~ |
// Fixed bit controller parameter width to 18bits |
// |
// Revision 1.12 2006/09/04 09:08:13 rherveille |
// fixed short scl high pulse after clock stretch |
// fixed slave model not returning correct '(n)ack' signal |
// |
// Revision 1.11 2004/05/07 11:02:26 rherveille |
// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit. |
// |
// Revision 1.10 2003/08/09 07:01:33 rherveille |
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. |
// Fixed a potential bug in the byte controller's host-acknowledge generation. |
// |
// Revision 1.9 2003/03/10 14:26:37 rherveille |
// Fixed cmd_ack generation item (no bug). |
// |
// Revision 1.8 2003/02/05 00:06:10 rherveille |
// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles. |
// |
// Revision 1.7 2002/12/26 16:05:12 rherveille |
// Small code simplifications |
// |
// Revision 1.6 2002/12/26 15:02:32 rherveille |
// Core is now a Multimaster I2C controller |
// |
// Revision 1.5 2002/11/30 22:24:40 rherveille |
// Cleaned up code |
// |
// Revision 1.4 2002/10/30 18:10:07 rherveille |
// Fixed some reported minor start/stop generation timing issuess. |
// |
// Revision 1.3 2002/06/15 07:37:03 rherveille |
// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment. |
// |
// Revision 1.2 2001/11/05 11:59:25 rherveille |
// Fixed wb_ack_o generation bug. |
// Fixed bug in the byte_controller statemachine. |
// Added headers. |
// |
|
// |
///////////////////////////////////// |
// Bit controller section |
///////////////////////////////////// |
// |
// Translate simple commands into SCL/SDA transitions |
// Each command has 5 states, A/B/C/D/idle |
// |
// start: SCL ~~~~~~~~~~\____ |
// SDA ~~~~~~~~\______ |
// x | A | B | C | D | i |
// |
// repstart SCL ____/~~~~\___ |
// SDA __/~~~\______ |
// x | A | B | C | D | i |
// |
// stop SCL ____/~~~~~~~~ |
// SDA ==\____/~~~~~ |
// x | A | B | C | D | i |
// |
//- write SCL ____/~~~~\____ |
// SDA ==X=========X= |
// x | A | B | C | D | i |
// |
//- read SCL ____/~~~~\____ |
// SDA XXXX=====XXXX |
// x | A | B | C | D | i |
// |
|
// Timing: Normal mode Fast mode |
/////////////////////////////////////////////////////////////////////// |
// Fscl 100KHz 400KHz |
// Th_scl 4.0us 0.6us High period of SCL |
// Tl_scl 4.7us 1.3us Low period of SCL |
// Tsu:sta 4.7us 0.6us setup time for a repeated start condition |
// Tsu:sto 4.0us 0.6us setup time for a stop conditon |
// Tbuf 4.7us 1.3us Bus free time between a stop and start condition |
// |
|
// synopsys translate_off |
`include "timescale.v" |
// synopsys translate_on |
|
`include "i2c_master_slave_defines.v" |
|
module i2c_master_bit_ctrl ( |
input clk, // system clock |
input rst, // synchronous active high reset |
input nReset, // asynchronous active low reset |
input ena, // core enable signal |
|
input [15:0] clk_cnt, // clock prescale value |
|
input [ 3:0] cmd, // command (from byte controller) |
output reg cmd_ack, // command complete acknowledge |
output reg busy, // i2c bus busy |
output reg al, // i2c bus arbitration lost |
|
input din, |
output reg dout, |
|
input scl_i, // i2c clock line input |
output scl_o, // i2c clock line output |
output scl_oen, // i2c clock line output enable (active low) |
input sda_i, // i2c data line input |
output sda_o, // i2c data line output |
output sda_oen, // i2c data line output enable (active low) |
|
output reg slave_adr_received, |
output reg [7:0] slave_adr, |
input master_mode, |
output reg cmd_slave_ack, |
input [1:0] slave_cmd , |
input sl_wait, |
output slave_reset |
|
); |
|
|
// |
// variable declarations |
// |
|
reg [ 1:0] cSCL, cSDA; // capture SCL and SDA |
reg [ 2:0] fSCL, fSDA; // SCL and SDA filter inputs |
reg sSCL, sSDA; // filtered and synchronized SCL and SDA inputs |
reg dSCL, dSDA; // delayed versions of sSCL and sSDA |
reg dscl_oen; // delayed scl_oen |
reg sda_chk; // check SDA output (Multi-master arbitration) |
reg clk_en; // clock generation signals |
reg slave_wait; // slave inserts wait states |
reg [15:0] cnt; // clock divider counter (synthesis) |
reg [13:0] filter_cnt; // clock divider for filter |
|
|
// state machine variable |
reg [17:0] c_state; // synopsys enum_state |
reg [4:0] slave_state; |
// |
// module body |
// |
|
// whenever the slave is not ready it can delay the cycle by pulling SCL low |
// delay scl_oen |
always @(posedge clk) |
dscl_oen <= scl_oen; |
|
// slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low |
// slave_wait remains asserted until the slave releases SCL |
always @(posedge clk or negedge nReset) |
if (!nReset) slave_wait <= 1'b0; |
else slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL); |
|
// master drives SCL high, but another master pulls it low |
// master start counting down its low cycle now (clock synchronization) |
wire scl_sync = dSCL & ~sSCL & scl_oen; |
|
|
// generate clk enable signal |
always @(posedge clk or negedge nReset) |
if (~nReset) |
begin |
cnt <= 16'h0; |
clk_en <= 1'b1; |
end |
else if (rst || ~|cnt || !ena || scl_sync) |
begin |
cnt <= clk_cnt; |
clk_en <= 1'b1; |
end |
else if (slave_wait) |
begin |
cnt <= cnt; |
clk_en <= 1'b0; |
end |
else |
begin |
cnt <= cnt - 16'h1; |
clk_en <= 1'b0; |
end |
|
|
// generate bus status controller |
|
// capture SDA and SCL |
// reduce metastability risk |
always @(posedge clk or negedge nReset) |
if (!nReset) |
begin |
cSCL <= 2'b00; |
cSDA <= 2'b00; |
end |
else if (rst) |
begin |
cSCL <= 2'b00; |
cSDA <= 2'b00; |
end |
else |
begin |
cSCL <= {cSCL[0],scl_i}; |
cSDA <= {cSDA[0],sda_i}; |
end |
|
|
// filter SCL and SDA signals; (attempt to) remove glitches |
always @(posedge clk or negedge nReset) |
if (!nReset ) filter_cnt <= 14'h0; |
else if (rst || !ena ) filter_cnt <= 14'h0; |
else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency |
else filter_cnt <= filter_cnt -1; |
|
|
always @(posedge clk or negedge nReset) |
if (!nReset) |
begin |
fSCL <= 3'b111; |
fSDA <= 3'b111; |
end |
else if (rst) |
begin |
fSCL <= 3'b111; |
fSDA <= 3'b111; |
end |
else if (~|filter_cnt) |
begin |
fSCL <= {fSCL[1:0],cSCL[1]}; |
fSDA <= {fSDA[1:0],cSDA[1]}; |
end |
|
|
// generate filtered SCL and SDA signals |
always @(posedge clk or negedge nReset) |
if (~nReset) |
begin |
sSCL <= 1'b1; |
sSDA <= 1'b1; |
|
dSCL <= 1'b1; |
dSDA <= 1'b1; |
end |
else if (rst) |
begin |
sSCL <= 1'b1; |
sSDA <= 1'b1; |
|
dSCL <= 1'b1; |
dSDA <= 1'b1; |
end |
else |
begin |
sSCL <= &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]); |
sSDA <= &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]); |
|
dSCL <= sSCL; |
dSDA <= sSDA; |
end |
|
// detect start condition => detect falling edge on SDA while SCL is high |
// detect stop condition => detect rising edge on SDA while SCL is high |
reg sta_condition; |
reg sto_condition; |
|
|
|
|
always @(posedge clk or negedge nReset) |
if (~nReset) |
begin |
sta_condition <= 1'b0; |
sto_condition <= 1'b0; |
end |
else if (rst) |
begin |
sta_condition <= 1'b0; |
sto_condition <= 1'b0; |
end |
else |
begin |
sta_condition <= ~sSDA & dSDA & sSCL; |
sto_condition <= sSDA & ~dSDA & sSCL; |
end |
|
|
// generate i2c bus busy signal |
always @(posedge clk or negedge nReset) |
if (!nReset) busy <= 1'b0; |
else if (rst ) busy <= 1'b0; |
else busy <= (sta_condition | busy) & ~sto_condition; |
|
// |
// generate arbitration lost signal |
// aribitration lost when: |
// 1) master drives SDA high, but the i2c bus is low |
// 2) stop detected while not requested |
reg cmd_stop; |
always @(posedge clk or negedge nReset) |
if (~nReset) |
cmd_stop <= 1'b0; |
else if (rst) |
cmd_stop <= 1'b0; |
else if (clk_en) |
cmd_stop <= cmd == `I2C_CMD_STOP; |
|
always @(posedge clk or negedge nReset) |
if (~nReset) |
al <= 1'b0; |
else if (rst) |
al <= 1'b0; |
else |
al <= (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop); |
|
|
// generate dout signal (store SDA on rising edge of SCL) |
always @(posedge clk) |
if (sSCL & ~dSCL) dout <= sSDA; |
|
|
// generate statemachine |
|
// nxt_state decoder |
parameter [17:0] idle = 18'b0_0000_0000_0000_0000; |
parameter [17:0] start_a = 18'b0_0000_0000_0000_0001; |
parameter [17:0] start_b = 18'b0_0000_0000_0000_0010; |
parameter [17:0] start_c = 18'b0_0000_0000_0000_0100; |
parameter [17:0] start_d = 18'b0_0000_0000_0000_1000; |
parameter [17:0] start_e = 18'b0_0000_0000_0001_0000; |
parameter [17:0] stop_a = 18'b0_0000_0000_0010_0000; |
parameter [17:0] stop_b = 18'b0_0000_0000_0100_0000; |
parameter [17:0] stop_c = 18'b0_0000_0000_1000_0000; |
parameter [17:0] stop_d = 18'b0_0000_0001_0000_0000; |
parameter [17:0] rd_a = 18'b0_0000_0010_0000_0000; |
parameter [17:0] rd_b = 18'b0_0000_0100_0000_0000; |
parameter [17:0] rd_c = 18'b0_0000_1000_0000_0000; |
parameter [17:0] rd_d = 18'b0_0001_0000_0000_0000; |
parameter [17:0] wr_a = 18'b0_0010_0000_0000_0000; |
parameter [17:0] wr_b = 18'b0_0100_0000_0000_0000; |
parameter [17:0] wr_c = 18'b0_1000_0000_0000_0000; |
parameter [17:0] wr_d = 18'b1_0000_0000_0000_0000; |
reg scl_oen_master ; |
reg sda_oen_master ; |
reg sda_oen_slave; |
reg scl_oen_slave; |
|
always @(posedge clk or negedge nReset) |
if (!nReset) |
begin |
c_state <= idle; |
cmd_ack <= 1'b0; |
scl_oen_master <= 1'b1; |
sda_oen_master <= 1'b1; |
sda_chk <= 1'b0; |
end |
else if (rst | al) |
begin |
c_state <= idle; |
cmd_ack <= 1'b0; |
scl_oen_master <= 1'b1; |
sda_oen_master <= 1'b1; |
sda_chk <= 1'b0; |
end |
else |
begin |
cmd_ack <= 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle |
|
if (clk_en ) |
case (c_state) // synopsys full_case parallel_case |
// idle state |
idle: |
begin |
case (cmd) // synopsys full_case parallel_case |
`I2C_CMD_START: c_state <= start_a; |
`I2C_CMD_STOP: c_state <= stop_a; |
`I2C_CMD_WRITE: c_state <= wr_a; |
`I2C_CMD_READ: c_state <= rd_a; |
default: c_state <= idle; |
endcase |
|
scl_oen_master <= scl_oen_master; // keep SCL in same state |
sda_oen_master <= sda_oen_master; // keep SDA in same state |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
// start |
start_a: |
begin |
c_state <= start_b; |
scl_oen_master <= scl_oen_master; // keep SCL in same state |
sda_oen_master <= 1'b1; // set SDA high |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
start_b: |
begin |
c_state <= start_c; |
scl_oen_master <= 1'b1; // set SCL high |
sda_oen_master <= 1'b1; // keep SDA high |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
start_c: |
begin |
c_state <= start_d; |
scl_oen_master <= 1'b1; // keep SCL high |
sda_oen_master <= 1'b0; // set SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
start_d: |
begin |
c_state <= start_e; |
scl_oen_master <= 1'b1; // keep SCL high |
sda_oen_master <= 1'b0; // keep SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
start_e: |
begin |
c_state <= idle; |
cmd_ack <= 1'b1; |
scl_oen_master <= 1'b0; // set SCL low |
sda_oen_master <= 1'b0; // keep SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
// stop |
stop_a: |
begin |
c_state <= stop_b; |
scl_oen_master <= 1'b0; // keep SCL low |
sda_oen_master <= 1'b0; // set SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
stop_b: |
begin |
c_state <= stop_c; |
scl_oen_master <= 1'b1; // set SCL high |
sda_oen_master <= 1'b0; // keep SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
stop_c: |
begin |
c_state <= stop_d; |
scl_oen_master <= 1'b1; // keep SCL high |
sda_oen_master <= 1'b0; // keep SDA low |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
stop_d: |
begin |
c_state <= idle; |
cmd_ack <= 1'b1; |
scl_oen_master <= 1'b1; // keep SCL high |
sda_oen_master <= 1'b1; // set SDA high |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
// read |
rd_a: |
begin |
c_state <= rd_b; |
scl_oen_master <= 1'b0; // keep SCL low |
sda_oen_master <= 1'b1; // tri-state SDA |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
rd_b: |
begin |
c_state <= rd_c; |
scl_oen_master <= 1'b1; // set SCL high |
sda_oen_master <= 1'b1; // keep SDA tri-stated |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
rd_c: |
begin |
c_state <= rd_d; |
scl_oen_master <= 1'b1; // keep SCL high |
sda_oen_master <= 1'b1; // keep SDA tri-stated |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
rd_d: |
begin |
c_state <= idle; |
cmd_ack <= 1'b1; |
scl_oen_master <= 1'b0; // set SCL low |
sda_oen_master <= 1'b1; // keep SDA tri-stated |
sda_chk <= 1'b0; // don't check SDA output |
end |
|
// write |
wr_a: |
begin |
c_state <= wr_b; |
scl_oen_master <= 1'b0; // keep SCL low |
sda_oen_master <= din; // set SDA |
sda_chk <= 1'b0; // don't check SDA output (SCL low) |
end |
|
wr_b: |
begin |
c_state <= wr_c; |
scl_oen_master <= 1'b1; // set SCL high |
sda_oen_master <= din; // keep SDA |
sda_chk <= 1'b0; // don't check SDA output yet |
// allow some time for SDA and SCL to settle |
end |
|
wr_c: |
begin |
c_state <= wr_d; |
scl_oen_master <= 1'b1; // keep SCL high |
sda_oen_master <= din; |
sda_chk <= 1'b1; // check SDA output |
end |
|
wr_d: |
begin |
c_state <= idle; |
cmd_ack <= 1'b1; |
scl_oen_master <= 1'b0; // set SCL low |
sda_oen_master <= din; |
sda_chk <= 1'b0; // don't check SDA output (SCL low) |
end |
|
endcase |
|
|
|
end |
|
//----------Addition for slave mode... |
reg [3:0] slave_cnt; |
|
//The SCL can only be driven when Master mode |
|
assign sda_oen = master_mode ? sda_oen_master : sda_oen_slave ; |
assign scl_oen = master_mode ? scl_oen_master : scl_oen_slave ; |
reg slave_act; |
reg slave_adr_received_d; |
|
//A 1 cycle pulse slave_adr_recived is generated when a slave adress is recvied after a startcommand. |
|
always @(posedge clk or negedge nReset) |
if (!nReset) begin |
slave_adr <= 8'h0; |
slave_cnt <= 4'h8; |
slave_adr_received <= 1'b0; |
slave_act <= 1'b0; |
end |
else begin |
slave_adr_received <= 1'b0; |
|
if ((sSCL & ~dSCL) && slave_cnt != 4'h0 && slave_act) begin |
slave_adr <= {slave_adr[6:0], sSDA}; |
slave_cnt <= slave_cnt -1; |
end |
else if (slave_cnt == 4'h0 && !sta_condition && slave_act) begin |
slave_adr_received <= 1'b1; |
slave_act <= 1'b0; |
end |
|
if (sta_condition) begin |
slave_cnt <= 4'h8; |
slave_adr <= 8'h0; |
slave_adr_received <= 1'b0; |
slave_act <= 1'b1; |
end |
if(sto_condition) begin |
slave_adr_received <= 1'b0; |
slave_act <= 1'b0; |
end |
end |
|
|
|
parameter [4:0] slave_idle = 5'b0_0000; |
parameter [4:0] slave_wr = 5'b0_0001; |
parameter [4:0] slave_wr_a = 5'b0_0010; |
parameter [4:0] slave_rd = 5'b0_0100; |
parameter [4:0] slave_rd_a = 5'b0_1000; |
parameter [4:0] slave_wait_next_cmd_1 = 5'b1_0000; |
parameter [4:0] slave_wait_next_cmd_2 = 5'b1_0001; |
|
always @(posedge clk or negedge nReset) |
if (!nReset) |
begin |
slave_state <= slave_idle; |
cmd_slave_ack <= 1'b0; |
sda_oen_slave <= 1'b1; |
scl_oen_slave <= 1'b1; |
end |
else if (rst | sta_condition || !ena) |
begin |
slave_state <= slave_idle; |
cmd_slave_ack <= 1'b0; |
sda_oen_slave <= 1'b1; |
scl_oen_slave <= 1'b1; |
end |
else |
begin |
cmd_slave_ack <= 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle |
|
if (sl_wait) |
scl_oen_slave <= 1'b0; |
else |
scl_oen_slave <= 1'b1; |
|
case (slave_state) |
slave_idle: |
|
begin |
|
case (slave_cmd) // synopsys full_case parallel_case |
`I2C_SLAVE_CMD_WRITE: slave_state <= slave_wr; |
`I2C_SLAVE_CMD_READ: slave_state <= slave_rd; |
default: |
begin |
slave_state <= slave_idle; |
sda_oen_slave <= 1'b1; // Moved this here, JB |
end |
endcase |
end |
|
slave_wr: |
begin |
if (~sSCL & ~dSCL) begin //SCL = LOW |
slave_state <= slave_wr_a; |
sda_oen_slave <= din; |
end |
end |
|
slave_wr_a: |
begin |
if (~sSCL & dSCL) begin //SCL FALLING EDGE |
cmd_slave_ack <= 1'b1; |
slave_state <= slave_wait_next_cmd_1; |
end |
end |
|
slave_wait_next_cmd_1: |
slave_state <= slave_wait_next_cmd_2; |
|
slave_wait_next_cmd_2: |
slave_state <= slave_idle; |
|
|
slave_rd: |
begin |
if (sSCL & ~dSCL) begin |
slave_state <= slave_rd_a; |
end |
end |
|
slave_rd_a: |
begin |
if (~sSCL & dSCL) begin |
cmd_slave_ack <= 1'b1; |
slave_state <= slave_wait_next_cmd_1; |
end |
end |
endcase // case (slave_state) |
end |
|
assign slave_reset = sta_condition | sto_condition; |
|
// assign scl and sda output (always gnd) |
assign scl_o = 1'b0; |
assign sda_o = 1'b0; |
|
endmodule |
/verilog/include/eth_defines.v
3,15 → 3,13
//// eth_defines.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://www.opencores.org/projects/ethmac/ //// |
//// Altered by Julius Baxter, julius.baxter@orsoc.se, increasing //// |
//// TX fifo buffer size, and uncommenting WB_B3 compat define //// |
//// http://opencores.org/project,ethmac //// |
//// //// |
//// Author(s): //// |
//// - Igor Mohor (igorM@opencores.org) //// |
//// //// |
//// All additional information is available in the Readme.txt //// |
//// file. //// |
//// Modified by: //// |
//// - Julius Baxter (julius@opencores.org) //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
39,144 → 37,9
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.33 2003/11/12 18:24:58 tadejm |
// WISHBONE slave changed and tested from only 32-bit accesss to byte access. |
// |
// Revision 1.32 2003/10/17 07:46:13 markom |
// mbist signals updated according to newest convention |
// |
// Revision 1.31 2003/08/14 16:42:58 simons |
// Artisan ram instance added. |
// |
// Revision 1.30 2003/06/13 11:55:37 mohor |
// Define file in eth_cop.v is changed to eth_defines.v. Some defines were |
// moved from tb_eth_defines.v to eth_defines.v. |
// |
// Revision 1.29 2002/11/19 18:13:49 mohor |
// r_MiiMRst is not used for resetting the MIIM module. wb_rst used instead. |
// |
// Revision 1.28 2002/11/15 14:27:15 mohor |
// Since r_Rst bit is not used any more, default value is changed to 0xa000. |
// |
// Revision 1.27 2002/11/01 18:19:34 mohor |
// Defines fixed to use generic RAM by default. |
// |
// Revision 1.26 2002/10/24 18:53:03 mohor |
// fpga define added. |
// |
// Revision 1.3 2002/10/11 16:57:54 igorm |
// eth_defines.v tagged with rel_5 used. |
// |
// Revision 1.25 2002/10/10 16:47:44 mohor |
// Defines changed to have ETH_ prolog. |
// ETH_WISHBONE_B# define added. |
// |
// Revision 1.24 2002/10/10 16:33:11 mohor |
// Bist added. |
// |
// Revision 1.23 2002/09/23 18:22:48 mohor |
// Virtual Silicon RAM might be used in the ASIC implementation of the ethernet |
// core. |
// |
// Revision 1.22 2002/09/04 18:36:49 mohor |
// Defines for control registers added (ETH_TXCTRL and ETH_RXCTRL). |
// |
// Revision 1.21 2002/08/16 22:09:47 mohor |
// Defines for register width added. mii_rst signal in MIIMODER register |
// changed. |
// |
// Revision 1.20 2002/08/14 19:31:48 mohor |
// Register TX_BD_NUM is changed so it contains value of the Tx buffer descriptors. No |
// need to multiply or devide any more. |
// |
// Revision 1.19 2002/07/23 15:28:31 mohor |
// Ram , used for BDs changed from generic_spram to eth_spram_256x32. |
// |
// Revision 1.18 2002/05/03 10:15:50 mohor |
// Outputs registered. Reset changed for eth_wishbone module. |
// |
// Revision 1.17 2002/04/24 08:52:19 mohor |
// Compiler directives added. Tx and Rx fifo size incremented. A "late collision" |
// bug fixed. |
// |
// Revision 1.16 2002/03/19 12:53:29 mohor |
// Some defines that are used in testbench only were moved to tb_eth_defines.v |
// file. |
// |
// Revision 1.15 2002/02/26 16:11:32 mohor |
// Number of interrupts changed |
// |
// Revision 1.14 2002/02/16 14:03:44 mohor |
// Registered trimmed. Unused registers removed. |
// |
// Revision 1.13 2002/02/16 13:06:33 mohor |
// EXTERNAL_DMA used instead of WISHBONE_DMA. |
// |
// Revision 1.12 2002/02/15 10:58:31 mohor |
// Changed that were lost with last update put back to the file. |
// |
// Revision 1.11 2002/02/14 20:19:41 billditt |
// Modified for Address Checking, |
// addition of eth_addrcheck.v |
// |
// Revision 1.10 2002/02/12 17:01:19 mohor |
// HASH0 and HASH1 registers added. |
|
// Revision 1.9 2002/02/08 16:21:54 mohor |
// Rx status is written back to the BD. |
// |
// Revision 1.8 2002/02/05 16:44:38 mohor |
// Both rx and tx part are finished. Tested with wb_clk_i between 10 and 200 |
// MHz. Statuses, overrun, control frame transmission and reception still need |
// to be fixed. |
// |
// Revision 1.7 2002/01/23 10:28:16 mohor |
// Link in the header changed. |
// |
// Revision 1.6 2001/12/05 15:00:16 mohor |
// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors |
// instead of the number of RX descriptors). |
// |
// Revision 1.5 2001/12/05 10:21:37 mohor |
// ETH_RX_BD_ADR register deleted. ETH_RX_BD_NUM is used instead. |
// |
// Revision 1.4 2001/11/13 14:23:56 mohor |
// Generic memory model is used. Defines are changed for the same reason. |
// |
// Revision 1.3 2001/10/18 12:07:11 mohor |
// Status signals changed, Adress decoding changed, interrupt controller |
// added. |
// |
// Revision 1.2 2001/09/24 15:02:56 mohor |
// Defines changed (All precede with ETH_). Small changes because some |
// tools generate warnings when two operands are together. Synchronization |
// between two clocks domains in eth_wishbonedma.v is changed (due to ASIC |
// demands). |
// |
// Revision 1.1 2001/08/06 14:44:29 mohor |
// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). |
// Include files fixed to contain no path. |
// File names and module names changed ta have a eth_ prologue in the name. |
// File eth_timescale.v is used to define timescale |
// All pin names on the top module are changed to contain _I, _O or _OE at the end. |
// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O |
// and Mdo_OE. The bidirectional signal must be created on the top level. This |
// is done due to the ASIC tools. |
// |
// Revision 1.1 2001/07/30 21:23:42 mohor |
// Directory structure changed. Files checked and joind together. |
// |
// |
// |
// |
// |
|
|
|
//`define ETH_BIST // Bist for usage with Virtual Silicon RAMS |
|
`define ETH_MBIST_CTRL_WIDTH 3 // width of MBIST control bus |
/verilog/include/i2c_master_slave_defines.v
0,0 → 1,66
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE rev.B2 compliant I2C Master controller defines //// |
//// //// |
//// //// |
//// Author: Richard Herveille //// |
//// richard@asics.ws //// |
//// www.asics.ws //// |
//// //// |
//// Downloaded from: http://www.opencores.org/projects/i2c/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2001 Richard Herveille //// |
//// richard@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: i2c_master_defines.v,v 1.3 2001-11-05 11:59:25 rherveille Exp $ |
// |
// $Date: 2001-11-05 11:59:25 $ |
// $Revision: 1.3 $ |
// $Author: rherveille $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
|
|
// I2C registers wishbone addresses |
|
// bitcontroller states |
`define I2C_CMD_NOP 4'b0000 |
`define I2C_CMD_START 4'b0001 |
`define I2C_CMD_STOP 4'b0010 |
`define I2C_CMD_WRITE 4'b0100 |
`define I2C_CMD_READ 4'b1000 |
|
`define I2C_SLAVE_CMD_WRITE 2'b01 |
`define I2C_SLAVE_CMD_READ 2'b10 |
`define I2C_SLAVE_CMD_NOP 2'b00 |
|
|
|
/verilog/include/usbhostslave_hostslave_h.v
0,0 → 1,80
////////////////////////////////////////////////////////////////////// |
// usbHostSlave_h.v |
////////////////////////////////////////////////////////////////////// |
|
`ifdef usbHostSlave_h_vdefined |
`else |
`define usbHostSlave_h_vdefined |
|
// Version 0.6 - Feb 4th 2005. Fixed bit stuffing and de-stuffing. This version succesfully supports |
// control reads and writes to USB flash dongle |
// Version 0.7 - Feb 24th 2005. Added support for isochronous transfers, fixed resume, connect and disconnect |
// time outs, added low speed EOP keep alive. The TX bit rate is now controlled by |
// SIETransmitter, and takes account of the requirement that SOF, and PREAMBLE are always full |
// speed, and TX resume is always low speed. |
// Fixed read clock recovery (readUSBWireData.v) issue which was resulting |
// in missing receive packets. |
// Fixed broken SOF Sync mode (where transacations are synchronized with the SOF transmission) |
// by adding kludged delay to softranmit. This needs to be fixed properly. |
// This version has undergone limited testing |
// with full speed flash dongle, low speed keyboard, and a PC in full and low speed modes. |
// Version 0.8 - June 24th 2005. Added bus access to the host SOFTimer. This version has been tested |
// with uClinux, and is known to work with a full speed USB flash stick. |
// Moving Opencores project status from Beta to done. |
// TODO: Test isochronous mode, and low speed mode using uClinux driver |
// Create a seperate clock domain for the bus interface |
// Add frame period adjustment capability |
// Add compilation flags for slave only and host only versions |
// Create data bus width options beyond 8-bit |
// Version 1.0 - October 14th 2005. Seperated the bus clock from the usb logic clock |
// Removed TX and RX fifo status registers, and removed |
// TX fifo data count register. |
// Added RESET_CORE bit to HOST_SLAVE_CONTROL_REG. |
// Fixed slave mode bug which caused receive fifo to be filled with |
// incoming data when the slave was responding with a NAK, and the |
// data should have been discarded. |
// Version 1.1 - February 23rd 2006. Fixed bug related to 'noActivityTimeOut' |
// Previously the 'noActivityTimeOut' flag was repetitively pulsed whenever |
// there was no detected activity on the USB data lines. This caused an infrequent |
// misreporting of time out errors. 'noActivityTimeOut' is now only enabled when |
// the higher level state machines are actively looking for receive packets. |
// Modified USB RX data clock recovery, so that data is sampled during the middle |
// of a USB bit period. Fixed a bug which could result in double sampling |
// of USB RX data if clock phase adjustments were required in the middle of a |
// USB packet. |
// Version 1.2 - October 1st 2006. Small changes to .asf FSM's required |
// during migration to ActiveHDL 7.1. Released SystemC test bench. |
// Re-generated .v files using ActiveHDL 7.1 |
// Replaced individual timescale directives with `include "timescale.v |
// Renamed top level Altera wrapper from 'usbHostSlaveWrap' to |
// 'usbHostSlaveAvalonWrap' |
// Version 1.3 - March 22nd 2008. Fixed bug in 'readUSBWireData'. Added |
// synchronizer to incoming USB wire data to avoid |
// metastability, and delay hazards. Not entirely sure, but it appears that |
// this bug caused more problems with some of the newer low power FPGAs |
// Maybe because they are more prone to problems with metastable |
// inputs that feed logic functions causing excessive high speed |
// toggle activity, and disrupting nearby cicuits. |
// Version 2.0 - June 16th 2008. Added two new top level modules which |
// allow the instantiation of only host (usbHost.v), or only device |
// features. Added double sync stages between usbClk, and busClk domains |
// to fix possible metastability issues. Also modified synchronization to |
// allow operation with busClk frequency less than usbClk frequency (down to |
// 24MHz). Integrated full support for USB PHY. Prior to this modification |
// the user would need to instantiate a GPIO module to control USB speed, |
// D+ and D- pull-up control, and VBUS detect. Fixed bug in bus interface wb_ack. |
// Modified cross-clock synchronisation of fifo resets |
// Added usbDevice, a standalone usb device implementation of usbhostslave |
// no additional hardware or software required |
|
|
// Most significant nibble corresponds to major revision. |
// Least significant nibble corresponds to minor revision. |
`define USBHOSTSLAVE_VERSION_NUM 8'h20 |
|
//Host slave common registers |
`define HOST_SLAVE_CONTROL_REG 1'b0 |
`define HOST_SLAVE_VERSION_REG 1'b1 |
|
`endif //usbHostSlave_h_vdefined |
|
/verilog/include/usbhostslave_slavecontrol_h.v
0,0 → 1,86
////////////////////////////////////////////////////////////////////// |
// usbSlaveControl.v |
////////////////////////////////////////////////////////////////////// |
|
`ifdef usbSlaveControl_h_vdefined |
`else |
`define usbSlaveControl_h_vdefined |
|
//endPointConstants |
`define NUM_OF_ENDPOINTS 4 |
`define NUM_OF_REGISTERS_PER_ENDPOINT 4 |
`define BASE_INDEX_FOR_ENDPOINT_REGS 0 |
`define ENDPOINT_CONTROL_REG 0 |
`define ENDPOINT_STATUS_REG 1 |
`define ENDPOINT_TRANSTYPE_STATUS_REG 2 |
`define NAK_TRANSTYPE_STATUS_REG 3 |
`define EP0_CTRL_REG 5'h0 |
`define EP0_STS_REG 5'h1 |
`define EP0_TRAN_TYPE_STS_REG 5'h2 |
`define EP0_NAK_TRAN_TYPE_STS_REG 5'h3 |
`define EP1_CTRL_REG 5'h4 |
`define EP1_STS_REG 5'h5 |
`define EP1_TRAN_TYPE_STS_REG 5'h6 |
`define EP1_NAK_TRAN_TYPE_STS_REG 5'h7 |
`define EP2_CTRL_REG 5'h8 |
`define EP2_STS_REG 5'h9 |
`define EP2_TRAN_TYPE_STS_REG 5'ha |
`define EP2_NAK_TRAN_TYPE_STS_REG 5'hb |
`define EP3_CTRL_REG 5'hc |
`define EP3_STS_REG 5'hd |
`define EP3_TRAN_TYPE_STS_REG 5'he |
`define EP3_NAK_TRAN_TYPE_STS_REG 5'hf |
|
|
//SCRegIndices |
`define LAST_ENDP_REG = `BASE_INDEX_FOR_ENDPOINT_REGS + (`NUM_OF_REGISTERS_PER_ENDPOINT * `NUM_OF_ENDPOINTS) - 1 |
`define SC_CONTROL_REG 5'h10 |
`define SC_LINE_STATUS_REG 5'h11 |
`define SC_INTERRUPT_STATUS_REG 5'h12 |
`define SC_INTERRUPT_MASK_REG 5'h13 |
`define SC_ADDRESS 5'h14 |
`define SC_FRAME_NUM_MSP 5'h15 |
`define SC_FRAME_NUM_LSP 5'h16 |
`define SCREG_BUFFER_LEN 5'h17 |
//SCRXStatusRegIndices |
`define NAK_SET_MASK 8'h10 |
`define SC_CRC_ERROR_BIT 0 |
`define SC_BIT_STUFF_ERROR_BIT 1 |
`define SC_RX_OVERFLOW_BIT 2 |
`define SC_RX_TIME_OUT_BIT 3 |
`define SC_NAK_SENT_BIT 4 |
`define SC_STALL_SENT_BIT 5 |
`define SC_ACK_RXED_BIT 6 |
`define SC_DATA_SEQUENCE_BIT 7 |
//SCEndPointControlRegIndices |
`define ENDPOINT_ENABLE_BIT 0 |
`define ENDPOINT_READY_BIT 1 |
`define ENDPOINT_OUTDATA_SEQUENCE_BIT 2 |
`define ENDPOINT_SEND_STALL_BIT 3 |
`define ENDPOINT_ISO_ENABLE_BIT 4 |
//SCMasterControlegIndices |
`define SC_GLOBAL_ENABLE_BIT 0 |
`define SC_TX_LINE_STATE_LSBIT 1 |
`define SC_TX_LINE_STATE_MSBIT 2 |
`define SC_DIRECT_CONTROL_BIT 3 |
`define SC_FULL_SPEED_LINE_POLARITY_BIT 4 |
`define SC_FULL_SPEED_LINE_RATE_BIT 5 |
`define SC_CONNECT_TO_HOST_BIT 6 |
//SCinterruptRegIndices |
`define TRANS_DONE_BIT 0 |
`define RESUME_INT_BIT 1 |
`define RESET_EVENT_BIT 2 //Line has entered reset state or left reset state |
`define SOF_RECEIVED_BIT 3 |
`define NAK_SENT_INT_BIT 4 |
`define VBUS_DET_INT_BIT 5 |
//TXTransactionTypes |
`define SC_SETUP_TRANS 0 |
`define SC_IN_TRANS 1 |
`define SC_OUTDATA_TRANS 2 |
//timeOuts |
`define SC_RX_PACKET_TOUT 18 |
|
//line status reg |
`define VBUS_PRES_BIT 2 |
|
`endif //usbSlaveControl_h_vdefined |
/verilog/include/usbhostslave_constants_h.v
0,0 → 1,32
////////////////////////////////////////////////////////////////////// |
//// usbConstants_h.v |
/////////////////////////////////////////////////////////////////////// |
|
`ifdef usbConstants_h_vdefined |
`else |
`define usbConstants_h_vdefined |
|
//PIDTypes |
`define OUT 4'h1 |
`define IN 4'h9 |
`define SOF 4'h5 |
`define SETUP 4'hd |
`define DATA0 4'h3 |
`define DATA1 4'hb |
`define ACK 4'h2 |
`define NAK 4'ha |
`define STALL 4'he |
`define PREAMBLE 4'hc |
|
|
//PIDGroups |
`define SPECIAL 2'b00 |
`define TOKEN 2'b01 |
`define HANDSHAKE 2'b10 |
`define DATA 2'b11 |
|
// start of packet SyncByte |
`define SYNC_BYTE 8'h80 |
|
`endif //usbConstants_h_vdefined |
|
/verilog/include/usbhostslave_hostcontrol_h.v
0,0 → 1,75
////////////////////////////////////////////////////////////////////// |
// usbHostControl_h.v |
////////////////////////////////////////////////////////////////////// |
|
`ifdef usbHostControl_h_vdefined |
`else |
`define usbHostControl_h_vdefined |
|
//HCRegIndices |
`define TX_CONTROL_REG 4'h0 |
`define TX_TRANS_TYPE_REG 4'h1 |
`define TX_LINE_CONTROL_REG 4'h2 |
`define TX_SOF_ENABLE_REG 4'h3 |
`define TX_ADDR_REG 4'h4 |
`define TX_ENDP_REG 4'h5 |
`define FRAME_NUM_MSB_REG 4'h6 |
`define FRAME_NUM_LSB_REG 4'h7 |
`define INTERRUPT_STATUS_REG 4'h8 |
`define INTERRUPT_MASK_REG 4'h9 |
`define RX_STATUS_REG 4'ha |
`define RX_PID_REG 4'hb |
`define RX_ADDR_REG 4'hc |
`define RX_ENDP_REG 4'hd |
`define RX_CONNECT_STATE_REG 4'he |
`define HOST_SOF_TIMER_MSB_REG 4'hf |
|
`define HCREG_BUFFER_LEN 4'hf |
`define HCREG_MASK 4'hf |
|
//TXControlRegIndices |
`define TRANS_REQ_BIT 0 |
`define SOF_SYNC_BIT 1 |
`define PREAMBLE_ENABLE_BIT 2 |
`define ISO_ENABLE_BIT 3 |
|
//interruptRegIndices |
`define TRANS_DONE_BIT 0 |
`define RESUME_INT_BIT 1 |
`define CONNECTION_EVENT_BIT 2 |
`define SOF_SENT_BIT 3 |
|
//TXTransactionTypes |
`define SETUP_TRANS 0 |
`define IN_TRANS 1 |
`define OUTDATA0_TRANS 2 |
`define OUTDATA1_TRANS 3 |
|
//TXLineControlIndices |
`define TX_LINE_STATE_LSBIT 0 |
`define TX_LINE_STATE_MSBIT 1 |
`define DIRECT_CONTROL_BIT 2 |
`define FULL_SPEED_LINE_POLARITY_BIT 3 |
`define FULL_SPEED_LINE_RATE_BIT 4 |
|
//TXSOFEnableIndices |
`define SOF_EN_BIT 0 |
|
//SOFTimeConstants |
//`define SOF_TX_TIME 80 //Fix this. Need correct SOF TX interval |
//Note that 'SOF_TX_TIME' is 48000 - 3. This is to account for the delay in resetting the SOF timer |
`define SOF_TX_TIME 16'hbb7d //Correct SOF interval for 48MHz clock. |
//`define SOF_TX_MARGIN 2 |
`define SOF_TX_MARGIN 16'h0190 //This is the transmission time for 100 bytes. May need to tweak |
|
//Host RXStatusRegIndices |
`define HC_CRC_ERROR_BIT 0 |
`define HC_BIT_STUFF_ERROR_BIT 1 |
`define HC_RX_OVERFLOW_BIT 2 |
`define HC_RX_TIME_OUT_BIT 3 |
`define HC_NAK_RXED_BIT 4 |
`define HC_STALL_RXED_BIT 5 |
`define HC_ACK_RXED_BIT 6 |
`define HC_DATA_SEQUENCE_BIT 7 |
|
`endif //usbHostControl_h_vdefined |
/verilog/include/usbhostslave_serialinterfaceengine_h.v
0,0 → 1,108
////////////////////////////////////////////////////////////////////// |
// usbSerialInterfaceEngine_h.v |
////////////////////////////////////////////////////////////////////// |
|
`ifdef usbSerialInterfaceEngine_h_vdefined |
`else |
`define usbSerialInterfaceEngine_h_vdefined |
|
// Sampling frequency = 'FS_OVER_SAMPLE_RATE' * full speed bit rate = 'LS_OVER_SAMPLE_RATE' * low speed bit rate |
`define FS_OVER_SAMPLE_RATE 4 |
`define LS_OVER_SAMPLE_RATE 32 |
|
//timeOuts |
`define RX_PACKET_TOUT 18 |
`define RX_EDGE_DET_TOUT 7 |
|
//TXStreamControlTypes |
`define TX_DIRECT_CONTROL 8'h00 |
`define TX_RESUME_START 8'h01 |
`define TX_PACKET_START 8'h02 |
`define TX_PACKET_STREAM 8'h03 |
`define TX_PACKET_STOP 8'h04 |
`define TX_IDLE 8'h05 |
`define TX_LS_KEEP_ALIVE 8'h06 |
|
//RXStreamControlTypes |
`define RX_PACKET_START 0 |
`define RX_PACKET_STREAM 1 |
`define RX_PACKET_STOP 2 |
|
//USBLineStates |
// ONE_ZERO corresponds to differential 1. ie D+ = Hi, D- = Lo |
`define ONE_ZERO 2'b10 |
`define ZERO_ONE 2'b01 |
`define SE0 2'b00 |
`define SE1 2'b11 |
|
//RXStatusIndices |
`define CRC_ERROR_BIT 0 |
`define BIT_STUFF_ERROR_BIT 1 |
`define RX_OVERFLOW_BIT 2 |
`define NAK_RXED_BIT 3 |
`define STALL_RXED_BIT 4 |
`define ACK_RXED_BIT 5 |
`define DATA_SEQUENCE_BIT 6 |
|
//usbWireControlStates |
`define TRI_STATE 1'b0 |
`define DRIVE 1'b1 |
|
//limits |
`define MAX_CONSEC_SAME_BITS 4'h6 |
`define MAX_CONSEC_SAME_BITS_PLUS1 4'h7 |
// RESUME_RX_WAIT_TIME defines the time period for resume detection |
// The resume counter is incremented at the bit rate, so |
// RESUME_RX_WAIT_TIME = 29 corresponds to 30 * 1/12MHz = 2.5uS at full speed |
// and 30 * 1/1.5MHz = 20uS at low speed, both of which are within the USB spec of |
// 2.5uS <= resumeDetectTime <= 100uS |
`define RESUME_RX_WAIT_TIME 5'd29 |
//`define RESUME_WAIT_TIME_MINUS1 9 |
// 'HOST_TX_RESUME_TIME' assumes counter is incremented at low speed bit rate |
`ifdef SIM_COMPILE |
`define HOST_TX_RESUME_TIME 16'd10 |
`else |
`define HOST_TX_RESUME_TIME 16'd30000 //Host sends resume for 30000 * 1/1.5MHz = 20mS |
`endif |
//`define CONNECT_WAIT_TIME 8'd20 |
`define CONNECT_WAIT_TIME 8'd120 //Device connect detected after 120 * 1/48MHz = 2.5uS |
//`define DISCONNECT_WAIT_TIME 8'd20 |
`define DISCONNECT_WAIT_TIME 8'd120 //Device disconnect detected after 120 * 1/48MHz = 2.5uS |
|
//RXConnectStates |
`define DISCONNECT 2'b00 |
`define LOW_SPEED_CONNECT 2'b01 |
`define FULL_SPEED_CONNECT 2'b10 |
|
//TX_RX_InternalStreamTypes |
`define DATA_START 8'h00 |
`define DATA_STOP 8'h01 |
`define DATA_STREAM 8'h02 |
`define DATA_BIT_STUFF_ERROR 8'h03 |
|
//RXStMach states |
`define DISCONNECT_ST 4'h0 |
`define WAIT_FULL_SPEED_CONN_ST 4'h1 |
`define WAIT_LOW_SPEED_CONN_ST 4'h2 |
`define CONNECT_LOW_SPEED_ST 4'h3 |
`define CONNECT_FULL_SPEED_ST 4'h4 |
`define WAIT_LOW_SP_DISCONNECT_ST 4'h5 |
`define WAIT_FULL_SP_DISCONNECT_ST 4'h6 |
|
//RXBitStateMachStates |
`define IDLE_BIT_ST 2'b00 |
`define DATA_RECEIVE_BIT_ST 2'b01 |
`define WAIT_RESUME_ST 2'b10 |
`define RESUME_END_WAIT_ST 2'b11 |
|
//RXByteStateMachStates |
`define IDLE_BYTE_ST 3'b000 |
`define CHECK_SYNC_ST 3'b001 |
`define CHECK_PID_ST 3'b010 |
`define HS_BYTE_ST 3'b011 |
`define TOKEN_BYTE_ST 3'b100 |
`define DATA_BYTE_ST 3'b101 |
|
`endif //usbSerialInterfaceEngine_h_vdefined |
|
|
/verilog/include/usbhostslave_wishbonebus_h.v
0,0 → 1,35
////////////////////////////////////////////////////////////////////// |
// wishBoneBus_h.v |
////////////////////////////////////////////////////////////////////// |
|
`ifdef wishBoneBus_h_vdefined |
`else |
`define wishBoneBus_h_vdefined |
|
//memoryMap |
`define HCREG_BASE 8'h00 |
`define HCREG_BASE_PLUS_0X10 8'h10 |
`define HOST_RX_FIFO_BASE 8'h20 |
`define HOST_TX_FIFO_BASE 8'h30 |
`define SCREG_BASE 8'h40 |
`define SCREG_BASE_PLUS_0X10 8'h50 |
`define EP0_RX_FIFO_BASE 8'h60 |
`define EP0_TX_FIFO_BASE 8'h70 |
`define EP1_RX_FIFO_BASE 8'h80 |
`define EP1_TX_FIFO_BASE 8'h90 |
`define EP2_RX_FIFO_BASE 8'ha0 |
`define EP2_TX_FIFO_BASE 8'hb0 |
`define EP3_RX_FIFO_BASE 8'hc0 |
`define EP3_TX_FIFO_BASE 8'hd0 |
`define HOST_SLAVE_CONTROL_BASE 8'he0 |
`define ADDRESS_DECODE_MASK 8'hf0 |
|
//FifoAddresses |
`define FIFO_DATA_REG 3'b000 |
`define FIFO_STATUS_REG 3'b001 |
`define FIFO_DATA_COUNT_MSB 3'b010 |
`define FIFO_DATA_COUNT_LSB 3'b011 |
`define FIFO_CONTROL_REG 3'b100 |
|
`endif //wishBoneBus_h_vdefined |
|
/verilog/smii/smii_sync.v
0,0 → 1,82
/* |
* SMII sync generation module |
* |
* Generate sync to PHY, and for internal statemachines |
* |
* Julius Baxter, julius.baxter@orsoc.se |
* |
*/ |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
module smii_sync |
( |
// SMII sync |
output sync, |
// internal |
output [10:1] tx_state, |
output [10:1] next_tx_state, |
output [10:1] rx_state, |
|
// clock amd reset |
input clk, |
input rst |
); |
reg [10:1] next_tx_state_r; |
reg [10:1] tx_state_r; |
|
reg [10:1] rx_state_int; |
reg [10:1] rx_state_int2; |
reg [10:1] rx_state_int3; |
|
// sync shall go high every 10:th cycle |
always @ (posedge clk) |
if (rst) |
begin |
next_tx_state_r <= 10'b0000000010; |
tx_state_r <= 0; |
end |
else |
begin |
tx_state_r <= next_tx_state_r; |
next_tx_state_r <= {next_tx_state_r[9:1],next_tx_state_r[10]}; |
end |
|
assign tx_state = tx_state_r; |
assign next_tx_state = next_tx_state_r; |
assign sync = tx_state_r[1]; |
|
always @(posedge clk) |
begin |
rx_state_int <= {tx_state_r[9:1],tx_state_r[10]}; |
rx_state_int2 <= rx_state_int; |
rx_state_int3 <= rx_state_int2; |
end |
// rx_state counter is 2 clocks behind tx state due to flops in and out of |
// FPGA |
assign rx_state = rx_state_int3; |
|
endmodule // smii_sync |
/verilog/smii/smii_if.v
0,0 → 1,460
////////////////////////////////////////////////////////////////////// |
//// //// |
//// SMII //// |
//// //// |
//// Description //// |
//// Low pin count serial MII ethernet interface //// |
//// //// |
//// To Do: //// |
//// - //// |
//// //// |
//// Author(s): //// |
//// - Michael Unneback, unneback@opencores.org //// |
//// ORSoC AB michael.unneback@orsoc.se //// |
//// - Julius Baxter, julius@orsoc.se //// |
//// ORSoC AB //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
`include "synthesis-defines.v" |
`include "orpsoc-defines.v" // To determine synthesis technology. |
module smii_if |
( |
// SMII |
output tx, |
input rx, |
// MII |
// TX |
input [3:0] mtxd, |
input mtxen, |
input mtxerr, |
output mtx_clk, |
// RX |
output [3:0] mrxd, |
output mrxdv, |
output mrxerr, |
output mrx_clk, |
output mcoll, |
output reg mcrs, |
output reg speed, |
output reg duplex, |
output reg link, |
// internal |
input [10:1] tx_smii_state, |
input [10:1] next_tx_smii_state, |
input [10:1] rx_smii_state, |
// clock and reset |
input eth_clk, |
input eth_rst |
); |
|
reg [7:0] tx_data_reg; |
reg tx_data_reg_valid; |
reg a0; |
reg state_data; |
|
reg [3:0] rx_tmp; |
|
reg [3:0] rxd_nib; |
reg rxdv, rxerr; |
|
reg jabber; |
|
reg [10:1] tx_cnt; |
reg [10:1] rx_cnt; |
|
|
///////////////////////////////////////////////// |
// Transmit |
|
// Tx segment counter when !speed |
always @ (posedge eth_clk or posedge eth_rst) |
if (eth_rst) |
tx_cnt <= 10'b00_0000_0001; |
else if (tx_smii_state[10]) |
tx_cnt <= {tx_cnt[9:1],tx_cnt[10]}; |
|
// MII signals registered in eth_clk domain |
reg txen_r, txerr_r; |
// TX clock generation to the MAC |
reg mtx_clk_gen, mtx_clk_gen_reg, |
mtx_clk_gen_reg2, mtx_clk_gen_reg3, |
mtx_clk_gen_reg4, mtx_clk_gen_reg5, |
mtx_clk_gen_reg6, mtx_clk_gen_reg7, |
tx_first_clk_gen, |
tx_first_clk_reg, tx_first_clk_reg2, |
tx_first_clk_reg3, tx_first_clk_reg4, |
tx_first_clk_reg5, tx_first_clk_reg6, |
tx_first_clk_reg7; |
|
// Generate clocks when state is 2, and 7 when transmitting |
// We then sample the MII txen signal, to see if we have a valid data frame |
// coming up. We can do this 2 or 3 clocks after the MII tx clk. If we do it |
// 2 then we allow 2 cycles for our mtxen_r signal to propegate, doubling the |
// period contstraint for the path from mtxen_r to the stuff it controls in |
// eth_clk domain. If we allow 3 from the eth MAC, then all stuff on the |
// eth_clk side of mtxen_r must meet the 125MHz timing. |
// |
// Once the data is sampled at the right times (plenty after they come from |
// the eth MAC, should be no issues there), then it all propegates through |
// relatively various levels of registering, configured so that the signals |
// appear in the tx_bits[] vector at the right time to be registered once |
// more before before having its bits AND-OR selected based on the smii state |
// The final SMII TX bit is generated from a sync counter that is one ahead |
// of the one we output. |
|
wire tx_first_clk, tx_second_clk; |
assign tx_first_clk = (tx_smii_state[2] & |
( speed | ( !speed & tx_cnt[10]) ) ); |
assign tx_second_clk = (tx_smii_state[7] & |
txen_r & ( speed | ( !speed & tx_cnt[1]) ) ); |
|
always @(posedge eth_clk) |
if (eth_rst) |
mtx_clk_gen <= 1'b0; |
else if (mtx_clk_gen) |
mtx_clk_gen <= 1'b0; |
// Clock high |
else if (tx_first_clk | tx_second_clk) |
mtx_clk_gen <= 1'b1; |
|
always @(posedge eth_clk) |
mtx_clk_gen_reg <= mtx_clk_gen; |
|
always @(posedge eth_clk) |
mtx_clk_gen_reg2 <= mtx_clk_gen_reg; |
|
always @(posedge eth_clk) |
mtx_clk_gen_reg3 <= mtx_clk_gen_reg2; |
|
always @(posedge eth_clk) |
mtx_clk_gen_reg4 <= mtx_clk_gen_reg3; |
|
always @(posedge eth_clk) |
mtx_clk_gen_reg5 <= mtx_clk_gen_reg4; |
|
always @(posedge eth_clk) |
mtx_clk_gen_reg6 <= mtx_clk_gen_reg5; |
|
always @(posedge eth_clk) |
mtx_clk_gen_reg7 <= mtx_clk_gen_reg6; |
|
always @(posedge eth_clk) |
tx_first_clk_gen <= tx_first_clk; |
|
always @(posedge eth_clk) |
tx_first_clk_reg <= tx_first_clk_gen; |
|
always @(posedge eth_clk) |
tx_first_clk_reg2 <= tx_first_clk_reg; |
|
always @(posedge eth_clk) |
tx_first_clk_reg3 <= tx_first_clk_reg2; |
|
always @(posedge eth_clk) |
tx_first_clk_reg4 <= tx_first_clk_reg3; |
|
always @(posedge eth_clk) |
tx_first_clk_reg5 <= tx_first_clk_reg4; |
|
always @(posedge eth_clk) |
tx_first_clk_reg6 <= tx_first_clk_reg5; |
|
always @(posedge eth_clk) |
tx_first_clk_reg7 <= tx_first_clk_reg6; |
|
|
// Register MII TX enable |
always @(posedge eth_clk) |
if (eth_rst) |
txen_r <= 1'b0; |
else if (tx_first_clk_reg3) |
txen_r <= mtxen; |
|
// Register MII TX error |
always @(posedge eth_clk) |
if (eth_rst) |
txerr_r <= 1'b0; |
else if (tx_first_clk_reg3) |
txerr_r <= mtxerr; |
|
// Register indicating if we're going to sample the second nibble of data |
reg tx_nib_second; |
always @(posedge eth_clk) |
if (eth_rst) |
tx_nib_second <= 0; |
else if (mtx_clk_gen_reg4) |
begin |
if (!txen_r) |
tx_nib_second <= 0; |
else |
tx_nib_second <= ~tx_nib_second; |
end |
// Byte register, appropriately storing nibbles as we recieve them from MAC |
reg [7:0] mtxd_r; |
always @(posedge eth_clk) |
if (txen_r & mtx_clk_gen_reg4 & !tx_nib_second) |
mtxd_r[3:0] <= mtxd; |
else if (txen_r & mtx_clk_gen_reg4 & tx_nib_second) |
mtxd_r[7:4] <= mtxd; |
|
// Sample our registered version of txen_r when we generate our |
// "first" of the 2 TX clocks per frame. |
reg tx_state_or_data; // 0 = state, 1 = data |
always @ (posedge eth_clk) |
if (eth_rst) |
tx_state_or_data <= 0; |
else if (tx_first_clk_reg4) |
tx_state_or_data <= txen_r; |
|
reg [10:1] tx_bits, tx_bits_reg, tx_bits_reg2; |
always @(posedge eth_clk) |
begin |
tx_bits_reg <= tx_bits; |
tx_bits[1] <= txerr_r; |
tx_bits[2] <= tx_state_or_data; |
tx_bits[3] <= (tx_state_or_data) ? mtxd_r[0] : txerr_r; |
tx_bits[4] <= (tx_state_or_data) ? mtxd_r[1] : speed; |
tx_bits[5] <= (tx_state_or_data) ? mtxd_r[2] : duplex; |
tx_bits[6] <= (tx_state_or_data) ? mtxd_r[3] : link; |
tx_bits[7] <= (tx_state_or_data) ? mtxd_r[4] : 0; |
tx_bits[8] <= (tx_state_or_data) ? mtxd_r[5] : 1; |
tx_bits[9] <= (tx_state_or_data) ? mtxd_r[6] : 1; |
tx_bits[10] <= (tx_state_or_data) ? mtxd_r[7] : 1; |
end |
|
// Generate tx output bit one clock infront, because we register |
// in the IOB too. |
reg tx_bit; |
always @(posedge eth_clk) |
tx_bit <= |(tx_bits_reg & next_tx_smii_state); |
|
assign tx = tx_bit; |
|
`ifdef ACTEL |
|
wire GND; |
|
GND GND_1_net(.Y(GND)); |
CLKDLY Inst1(.CLK(mtx_clk_gen), .GL(mtx_clk), .DLYGL0(GND), .DLYGL1(GND), |
.DLYGL2(GND), .DLYGL3(GND), .DLYGL4(GND)) /* synthesis black_box */; |
/* |
gbuf mtx_clk_bufg |
( |
.CLK(mtx_clk_gen), |
.GL(mtx_clk) |
); |
*/ |
`else |
assign mtx_clk = mtx_clk_gen; |
`endif |
|
///////////////////////////////////////////////// |
// Receive |
|
`ifndef SYNTHESIS |
reg [79:0] rx_statename; |
always @* begin |
case (1) |
rx_smii_state[1] : |
rx_statename = "CRS"; |
rx_smii_state[2] : |
rx_statename = "RX_DV"; |
rx_smii_state[3]: |
rx_statename = "RXD0/RXERR"; |
rx_smii_state[4]: |
rx_statename = "RXD1/Fast"; |
rx_smii_state[5]: |
rx_statename = "RXD2/Dupl"; |
rx_smii_state[6]: |
rx_statename = "RXD3/Link"; |
rx_smii_state[7]: |
rx_statename = "RXD4/Jabb"; |
rx_smii_state[8]: |
rx_statename = "RXD5/UNV"; |
rx_smii_state[9]: |
rx_statename = "RXD6/FCD"; |
rx_smii_state[10] : |
rx_statename = "RXD7/AS1"; |
default: |
rx_statename = "XXXXXXX"; |
endcase // case (1) |
end // always @ * |
`endif |
|
reg rxdv_thisframe; |
wire rxdv_lastframe; |
reg rxdv_lastframe_r; |
reg [9:0] rxd_thisframe; |
reg [9:0] rxd_lastframe; |
|
// Logic to detect change in ethernet speed |
reg speed_r; |
always @(posedge eth_clk) |
speed_r <= speed; |
|
wire speed_edge; |
assign speed_edge = speed_r != speed; |
|
|
always @ (posedge eth_clk or posedge eth_rst) |
if (eth_rst) |
rx_cnt <= 10'd1; |
// Data coming in, or we've changed from fast to slow ethernet |
else if ((!rxdv_lastframe & rx_smii_state[8] & rxdv_thisframe) | speed_edge) |
rx_cnt[10] <= ~speed; // Will be high if not in 100MBit mode |
else if (rx_smii_state[10]) // wrap |
if (rx_cnt[10]) |
rx_cnt[10:1] <= {9'b000000000, ~speed}; // Clears bit when fasteth |
else |
rx_cnt <= {rx_cnt[9:1],1'b0}; |
|
always @(posedge eth_clk) |
if (rx_smii_state[2]) |
rxdv_thisframe <= rx; |
|
always @(posedge eth_clk) |
if (rx_smii_state[1]) |
mcrs <= rx; |
|
always @(posedge eth_clk) // shift register sampling incoming data |
rxd_thisframe <= {rx, rxd_thisframe[9:1]}; |
|
always @(posedge eth_clk) |
if (rx_smii_state[1]) |
rxd_lastframe <= rxd_thisframe; |
|
assign rxdv_lastframe = rxd_lastframe[1]; |
|
// Must remember with rxd_thisframe, data has been registered, so state |
// counter is 1 infront of what we have in it |
|
always @(posedge eth_clk) |
if (eth_rst) |
begin |
{rxdv, rxerr, speed, duplex, link, jabber} <= 6'b001110; |
end |
else |
begin |
if (rx_smii_state[10]) // Look at sampled shift reg |
begin |
if ((!rxdv_lastframe)) // !RX DV from last frame |
begin |
rxerr <= rxd_lastframe[2]; |
speed <= rxd_lastframe[3]; |
duplex <= rxd_lastframe[4]; |
link <= rxd_lastframe[5]; |
jabber <= rxd_lastframe[6]; |
// rxd_thisframe[7] should be 1 if |
end |
end |
end // else: !if(eth_rst) |
|
// Latch the nibbles at the appropriate moments |
always @(posedge eth_clk) |
if (rx_smii_state[2]) |
rxd_nib <= rxd_lastframe[5:2]; |
else if (rx_smii_state[8]) |
rxd_nib <= rxd_lastframe[9:6]; |
|
// Nibble write enables |
reg rx_we_nib0, rx_we_nib1; |
|
always @(posedge eth_clk) |
if (eth_rst) |
rx_we_nib0 <= 0; |
else if (rx_smii_state[3] & rxdv_lastframe & |
!(!rxdv_thisframe & rx)) |
// Check in state 3, if DV was high for buffered frame (lastframe), and |
// if the incoming frame doesn't negate it with error being signaled |
rx_we_nib0 <= 1; |
else |
rx_we_nib0 <= 0; |
|
always @(posedge eth_clk) |
if (eth_rst) |
rx_we_nib1 <= 0; |
else if (rx_smii_state[8] & !(!rxdv_thisframe & (rxd_thisframe[5] | !rx)) |
& rxdv_lastframe) |
// Check in state 8, if DV was high last frame, and this frame isn't a |
// status frame indicating either error or not upper nibble valid, in |
// which case we do not generate a WE to the FIFO |
rx_we_nib1 <= 1; |
else |
rx_we_nib1 <= 0; |
|
// Pipelining of clocks to MAC, this should run at 125MHz |
reg nib_rx_clock; |
always @(posedge eth_clk) |
nib_rx_clock <= ((rx_smii_state[4] & rx_we_nib0)|(rx_smii_state[9] & rx_we_nib1)); |
|
// Enable for mrxclk inbetween frame receive |
reg inbetween_rx_clock; |
always @(posedge eth_clk) |
inbetween_rx_clock <= rx_smii_state[4];//(!rxdv_thisframe & !rxdv_lastframe); |
|
// Enable to clock the segment in the 10MBit mode, change rx_cnt[x] to alter |
// which of the 10 the segments we use |
reg thissegment_rx_clock; |
always @(posedge eth_clk) |
thissegment_rx_clock <= speed | (rx_cnt[6] & !speed); |
|
reg mrx_clk_gen; |
// Receive MII clock generation (very similar to Receive FIFO WE generation) |
// This ends up being only about 20MHz when clocking in data |
always @(posedge eth_clk) |
if (eth_rst) |
mrx_clk_gen <= 0; |
else if (mrx_clk_gen) |
mrx_clk_gen <= 0; |
else if ((nib_rx_clock | inbetween_rx_clock) & thissegment_rx_clock ) |
mrx_clk_gen <= 1; |
|
`ifdef ACTEL |
|
|
CLKDLY Inst2(.CLK(mrx_clk_gen), .GL(mrx_clk), .DLYGL0(GND), .DLYGL1(GND), |
.DLYGL2(GND), .DLYGL3(GND), .DLYGL4(GND)) /* synthesis black_box */; |
|
/* |
gbuf mrx_clk_bufg |
( |
.CLK(mrx_clk_gen), |
.GL(mrx_clk) |
); |
*/ |
`else |
assign mrx_clk = mrx_clk_gen; |
`endif |
|
assign mrxd = rxd_nib; |
assign mrxdv = rxdv_lastframe; |
assign mrxerr = rxerr; |
|
assign mcoll = mcrs & mtxen & !duplex; |
|
endmodule // smii_if |
/verilog/smii/smii.v
0,0 → 1,142
/* |
* SMII <-> MII interface |
* |
* Julius Baxter, julius.baxter@orsoc.se |
* |
*/ |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2009, 2010 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
module smii |
( |
eth_clk, |
eth_rst, |
eth_sync_pad_o, |
eth_tx_pad_o, |
eth_rx_pad_i, |
mtxd, |
mtxen, |
mtxerr, |
mtx_clk, |
mrxd, |
mrxdv, |
mrxerr, |
mrx_clk, |
mcoll, |
mcrs, |
speed, |
duplex, |
link |
); |
|
input eth_clk; |
input eth_rst; // active high reset synchronous to ethernet clock |
|
// SMII |
output reg eth_sync_pad_o /*synthesis syn_useioff=1 syn_allow_retiming=0 syn_noprune=1*/; |
output reg eth_tx_pad_o /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
input eth_rx_pad_i; |
|
|
// MII |
// TX |
input [3:0] mtxd; |
input mtxen; |
input mtxerr; |
output mtx_clk; |
// RX |
output [3:0] mrxd; |
output mrxdv; |
output mrxerr; |
output mrx_clk; |
output mcoll; |
output mcrs; |
output speed; |
output duplex; |
output link; |
|
|
// Wires from pads |
wire smii_tx; |
reg smii_rx /*synthesis syn_useioff=1 syn_allow_retiming=0 */; |
|
|
// Sync generation |
wire [10:1] tx_smii_state; |
wire [10:1] next_tx_smii_state; |
wire [10:1] rx_smii_state; |
wire smii_sync; |
smii_sync smii_sync0 |
( |
.sync(smii_sync), |
.tx_state(tx_smii_state), |
.next_tx_state(next_tx_smii_state), |
.rx_state(rx_smii_state), |
.clk(eth_clk), |
.rst(eth_rst) |
); |
|
// IOB regs for SMII |
always @(posedge eth_clk) eth_sync_pad_o <= smii_sync; |
always @(posedge eth_clk) eth_tx_pad_o <= smii_tx; |
always @(posedge eth_clk) smii_rx <= eth_rx_pad_i; |
|
|
smii_if smii_if0 |
( |
// SMII signals |
.tx (smii_tx), |
.rx (smii_rx), |
.tx_smii_state (tx_smii_state[10:1]), |
.next_tx_smii_state (next_tx_smii_state[10:1]), |
.rx_smii_state (rx_smii_state[10:1]), |
// MAC MII receive |
.mrxd (mrxd[3:0]), |
.mrxdv (mrxdv), |
.mrxerr (mrxerr), |
.mrx_clk (mrx_clk), |
// MAC MII transmit |
.mtx_clk (mtx_clk), |
.mtxd (mtxd[3:0]), |
.mtxen (mtxen), |
.mtxerr (mtxerr), |
// Collision |
.mcoll (mcoll), |
// Carrier sense |
.mcrs (mcrs), |
// Speedy ethernet |
.speed (speed), |
// Duplex indicator |
.duplex (duplex), |
// Linke indicator |
.link (link), |
// Clocks, resets |
.eth_clk (eth_clk), |
.eth_rst (eth_rst) |
); |
|
endmodule // smii |
/verilog/smii/README
0,0 → 1,5
MII to SMII converter RTL |
|
This implements conversion between the 3-pin SMII bus and the higher-pin count MII interface for communication between a 10/100 ethernet MAC and ethernet PHY. |
|
|
/verilog/simple_spi/simple_spi.v
32,35 → 32,7
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: simple_spi_top.v,v 1.5 2004-02-28 15:59:50 rherveille Exp $ |
// |
// $Date: 2004-02-28 15:59:50 $ |
// $Revision: 1.5 $ |
// $Author: rherveille $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2003/08/01 11:41:54 rherveille |
// Fixed some timing bugs. |
// |
// Revision 1.3 2003/01/09 16:47:59 rherveille |
// Updated clkcnt size and decoding due to new SPR bit assignments. |
// |
// Revision 1.2 2003/01/07 13:29:52 rherveille |
// Changed SPR bits coding. |
// |
// Revision 1.1.1.1 2002/12/22 16:07:15 rherveille |
// Initial release |
// |
// |
|
|
|
// |
// Motorola MC68HC11E based SPI interface |
// |
// Currently only MASTER mode is supported |
136,56 → 108,10
reg [1:0] state; // statemachine state |
reg [2:0] bcnt; |
|
|
// Little startup init FSM and logic |
// Does 4 accesses and waits to read out the data so the module is |
// properly reset: |
// Write 1: 0x3 |
// Write 2: 0x0 |
// Write 3: 0x0 |
// Write 4: 0x0 |
// |
// This means anysoftware that wants to read can simply start pushing stuff |
// into the fifo to kick it off |
// |
reg [3:0] startup_state = 0; |
reg [3:0] startup_state_r = 0; |
parameter startup_state_reset = 0; // Set to 0x10 to init to read on startup |
parameter startup_spcr = 0; |
parameter startup_slave_select = 0; |
|
wire startup_rfre; |
wire startup_busy; |
assign startup_busy = |startup_state_r; |
|
|
always @(posedge clk_i) |
if (rst_i) |
startup_state <= startup_state_reset; |
else if ((startup_state == startup_state_r))// Whenever state is back to 0 |
startup_state <= {1'b0,startup_state[3:1]}; |
|
always @(posedge clk_i) |
if (rst_i) |
startup_state_r <= startup_state_reset; |
else if (startup_rfre) |
startup_state_r <= {1'b0,startup_state_r[3:1]}; |
|
wire [1:0] startup_state_wdf; |
// This sets the 0x3 command, to read |
assign startup_state_wdf = {startup_state[3], startup_state[3]}; |
|
wire startup_wfwe; |
assign startup_wfwe = startup_busy & (startup_state == startup_state_r & !rst_i); |
|
|
assign startup_rfre = (startup_busy) & !rfempty & |
(startup_state != startup_state_r); |
|
|
// |
// Wishbone interface |
wire wb_acc = cyc_i & stb_i & !startup_busy; // WISHBONE access |
wire wb_acc = cyc_i & stb_i; // WISHBONE access |
wire wb_wr = wb_acc & we_i; // WISHBONE write access |
|
// dat_i |
192,7 → 118,7
always @(posedge clk_i) |
if (`SIMPLE_SPI_RST_SENS) |
begin |
spcr <= 8'h10 | startup_spcr; // set master bit |
spcr <= 8'h10; // set master bit |
sper <= 8'h00; |
ss_r <= 0; |
end |
207,8 → 133,6
if (adr_i == 3'b100) |
ss_r <= dat_i[slave_select_width-1:0]; |
end // if (wb_wr) |
else if (startup_busy) |
ss_r <= startup_slave_select; |
|
// Slave select output |
// SPI slave select is active low |
287,12 → 211,12
|
|
wire [7:0] wfifo_dat_i; |
assign wfifo_dat_i = startup_busy ? {6'd0, startup_state_wdf} : dat_i; |
assign wfifo_dat_i = dat_i; |
|
wire wfifo_wfwe; |
assign wfifo_wfwe = wfwe | startup_wfwe; |
assign wfifo_wfwe = wfwe; |
|
wire rfifo_rfre = rfre | startup_rfre; |
wire rfifo_rfre = rfre; |
|
// |
// hookup read/write buffer fifo |