USB 2.0 HDL

XEM3001v1 Note

The first PCB revision of the XEM3001 (date code: 20040301) had an 8-bit host interface.  All newer implementations have a 16-bit interface.  For the purposes of this section, the only things which change are the HI_DATA, TI_DATA busses, as well as the widths of the endpoint connections (such as EP_DATAIN and EP_DATAOUT).  For the XEM3001v1, simply substitute an 8-bit bus in those places.

FPGA Resource Requirements

The FrontPanel-enabling modules have been designed to consume as few resources as possible within the FPGA.  The resource requirements for each block are listed in the tables below.  Keep in mind that these are requirements for an endpoint with all bits used.  In many cases, the place and route tools will optimize and remove unused components.

RESOURCESLICE FFS4-IN LUTSBLOCK RAMS
Host Interface33490
Wire In16140
Wire Out850
Trigger In32210
Trigger Out27150
Pipe In9100
Pipe Out060
BT Pipe In???
BT Pipe Out???

Wire-OR

Multiple endpoints are attached to the ok2 bus on the okHost by using a Wire-OR.  Each endpoint is told when it can assert its data on the bus.  At all other times, it drives 0.  The Wire-OR component performs a bitwise OR operation on each bit of the bus and outputs the result.  In this manner, multiple endpoints can share a bus without requiring the use of tristates or a large mux.

The okWireOR is provided as a parameterized helper module in okLibrary.v and okLibrary.vhd.  Please refer to the provided samples to see how to instantiate this module.

The Host Interface

The host interface is the gateway for FrontPanel to control and observe your design.  It contains relatively simple logic that lets the USB microcontroller on the device communicate with the various endpoints within the design.  Exactly one host interface must be instantiated in any design which uses the FrontPanel components.

The Host Interface component is the only block which is synthesized with your design.  It contains a Host Interface core component (provided as a pre-synthesized module) as well as the necessary IOB components to connect to the host interface pins of the FPGA.

NOTE: The okHost is contained in okLibrary.v or okLibrary.vhd.  Some details change from device to device so the exact pinouts may differ slightly from the documentation below.  Please see the Opal Kelly samples in the FrontPanel installation directory for examples specific to each supported device.

The diagram below illustrates the structural relationships between the various endpoints, the okWireOR, and okHost modules.

okHost

This module must be instantiated in any design that makes use of FrontPanel virtual interface components.  The following signals need to be connected directly to pins on the FPGA which go to the USB microcontroller on the device.  For a listing of the pin locations for a particular product, please see the user’s manual for that device.

SIGNALDIRECTIONDESCRIPTION
HI_IN[7:0]InputHost interface input signals.
HI_OUT[1:0]OutputHost interface output signals.
HI_INOUT[15:0]In/OutHost interface bidirectional signals.

The remaining ports of the okHost are connected to a shared bus inside your design.  These signals are collectively referred to as the target interface bus.  Each endpoint must connect to these signals for proper operation.

SIGNALDIRECTIONDESCRIPTION
OK1[30:0]OutputControl signals to the target endpoints.
OK2[16:0]InputControl signals from the target endpoints.
TI_CLKOutputBuffered copy of the host interface clock (48 MHz).  This signal does not need to be connected to the target endpoints because it is replicated within OK1.

Instantiation of the okHost is simple in either VHDL or Verilog.  Use the templates below in your toplevel HDL design.  A more detailed listing can be found later in this manual as one of the examples.

VERILOG INSTANTIATION

okHost hostIF (.hi_in(hi_in),.hi_out(hi_out), .hi_inout(hi_inout),.ti_clk(ticlk), .ok1(ok1), .ok2(ok2));
Code language: CSS (css)

VHDL INSTANTIATION

okHI : okHost port map (hi_in => hi_in,hi_out => hi_out, hi_inout => hi_inout,ti_clk => ticlk, ok1 => ok1, ok2 => ok2);
Code language: PHP (php)

Each endpoint is connected to 48 target interface pins on the okHost module.  The direction is from the perspective of the endpoint module.

SIGNALDIRECTIONDESCRIPTION
OK1[30:0]InputInterface control (HI to target).
OK2[16:0]OutputInterface control (Target to HI).

These signals are present in every endpoint.  In the signal tables for the independent endpoints below, we have left out these common signals.

okWireIn

In addition to the target interface pins, the okWireIn adds a single 16-bit output bus called EP_DATAOUT[15:0].  The pins of this bus are connected to your design as wires and act as asynchronous connections from FrontPanel components to your HDL.

When FrontPanel updates the Wire Ins, it writes new values to the wires, then updates them all at the same time.  Therefore, although the wires are asynchronous endpoints, they are all updated at the same time on the host interface clock.

SIGNALDIRECTIONDESCRIPTION
EP_DATAOUT[15:0]OutputWire values output. (sent from host)

VERILOG INSTANTIATION

okWireIn wire03 (.ok1(ok1),.ep_addr(8'h03), .ep_dataout(ep03data));

VHDL INSTANTIATION

wire03 : okWireIn port map (ok1 => ok1,ep_addr => x"03", ep_dataout => ep03data);
Code language: PHP (php)

okWireOut

An okWireOut module adds a single 16-bit input bus called EP_DATAIN[15:0].  Signals on these pins are read whenever FrontPanel updates the state of its wire values.  In fact, all wires are captured simultaneously (synchronous to the host interface clock) and read out sequentially.

SIGNALDIRECTIONDESCRIPTION
EP_DATAIN[15:0]InputWire values input. (to be sent to host)

VERILOG INSTANTIATION

okWireOut wire21 (.ok1(ok1), .ok2(ok2),.ep_addr(8'h21), .ep_datain(ep21data));

VHDL INSTANTIATION

wire21 : okWireOut port map (ok1 => ok1, ok2 => ok2,ep_addr => x"21", ep_datain => ep21data);
Code language: PHP (php)

okTriggerIn

The okTriggerIn provides EP_CLK and EP_TRIGGER[15:0] as interface signals.  The Trigger In endpoint produces a single-cycle trigger pulse on any of EP_TRIGGER[15:0] which is synchronized to the clock signal EP_CLK.  Therefore, the single-cycle does not necessarily have to be a single host interface cycle.  Rather, the module takes care of crossing the clock boundary properly.

SIGNALDIRECTIONDESCRIPTION
EP_ADDR[7:0]InputEndpoint address.
EP_CLKInputClock to which the trigger should synchronize.
EP_TRIGGER[15:0]OutputIndependent triggers from host.

VERILOG INSTANTIATION

okTriggerIn trigIn53 (.ok1(ok1),.ep_addr(8'h53), .ep_clk(clk2), .ep_trigger(ep53trig));

VHDL INSTANTIATION

trigIn53 : okTriggerIn port map (ok1 => ok1,ep_addr => x"53", ep_clk => clk2, ep_trigger => ep53trig);
Code language: PHP (php)

okTriggerOut

The target may trigger the host using this module.  EP_TRIGGER[15:0] contains 16 independent trigger signals which are monitored with respect to EP_CLK.  If EP_TRIGGER[x] is asserted for the rising edge of EP_CLK, then that trigger will be set.  The next time the host checks trigger values, the triggers will be cleared.

SIGNALDIRECTIONDESCRIPTION
EP_ADDR[7:0]InputEndpoint address.
EP_CLKInputClock to which the trigger is synchronized.
EP_TRIGGER[15:0]InputIndependent triggers to host.

VERILOG INSTANTIATION

okTriggerOut trigOut6A (.ok1(ok1), .ok2(ok2),.ep_addr(8'h6a), .ep_clk(clk2), .ep_trigger(ep6Atrig));

VHDL INSTANTIATION

trigOut6A : okTriggerOut port map (ok1 => ok1, ok2 => ok2,ep_addr => x"6a", ep_clk => clk2, ep_trigger => ep6Atrig);
Code language: PHP (php)

okPipeIn

The okPipeIn module provides a way to move synchronous multi-byte data from the host to the target.  As usual, the host is the master and therefore the target must accept data as it is moved through this pipe (up to 48 MHz).  The EP_WRITE signal is an active high signal which is asserted when data is to be accepted by the target on EP_DATAOUT[15:0].  It is possible that EP_WRITE be asserted for several consecutive cycles without deasserting.  In such a case, EP_DATAOUT[15:0] will be changing every clock.

This somewhat simple Pipe In implementation requires that the target interface be very responsive to incoming pipe data.  If the target is able to keep up with the throughput, but needs to handle data in a block fashion, coupling the okPipeIn with a FIFO (from the Xilinx CORE generator) is a good solution.  Alternatively, an okBTPipeIn can be used.

The timing diagram below indicates how data is presented by the okPipeIn to user HDL.  EP_DATAOUT contains valid data for any clock cycle where EP_WRITE is asserted during the rising edge of TI_CLK.  Note that the transfer sends 4 words in this example.  Although contrived, it is important to note that EP_WRITE may deassert during the transfer.  This will generally happen with longer transfers (>256 words).

SIGNALDIRECTIONDESCRIPTION
EP_ADDR[7:0]InputEndpoint address.
EP_DATAOUT[15:0]OutputPipe data output.
EP_WRITEOutputActive high write signal.  Data should be captured when this signal is asserted.

VERILOG INSTANTIATION

okPipeIn pipeIn9C (.ok1(ok1), .ok2(ok2),.ep_addr(8'h9c), .ep_dataout(ep9Cpipe), .ep_write(ep9Cwrite));

VHDL INSTANTIATION

pipeIn9C : okPipeIn port map (ok1 => ok1, ok2 => ok2,ep_addr => x"9c", ep_dataout => ep9Cpipe, ep_write => ep9Cwrite);
Code language: PHP (php)

okPipeOut

The okPipeOut module implements a simple version of the Pipe Out endpoint to move synchronous multi-byte data from the target to the host.  Because the host is master, all reads (on the target side) occur at the host’s whim.  Therefore, data must be provided whenever EP_READ is asserted.

This simple implementation of a Pipe Out endpoint requires that the target interface be somewhat responsive to host read requests.  If the target is able to keep up with the throughput, but needs to handle data in a block fashion, coupling the okPipeOut with a FIFO (from the Xilinx CORE generator) is a good solution.  Alternatively, an okBTPipeOut can be used.

The timing diagram below indicates how the user HDL needs to respond to EP_READ with EP_DATAIN valid data.  When EP_READ is asserted for the rising edge of TI_CLK, user HDL must respond with valid EP_DATAIN on the next clock edge, subject to setup and hold times appropriate for (TAS and TAH in the FPGA CLB timing documentation).  Of course, these times are also subject to the particular routing and logic in your HDL implementation.  Note that the transfer sends 4 words in this example.  Although contrived, it is important to note that EP_READ may deassert during the transfer.  This will generally happen with longer transfers (>256 words).

SIGNALDIRECTIONDESCRIPTION
EP_ADDR[7:0]InputEndpoint address.
EP_DATAIN[15:0]InputPipe data input.
EP_READOutputActive-high read signal.  Data must be provided in the cycle following as assertion of this signal.

VERILOG INSTANTIATION

okPipeOut pipeOutA3 (.ok1(ok1), .ok2(ok2),.ep_addr(8'ha3), .ep_datain(epA3pipe), .ep_read(epA3read));

VHDL INSTANTIATION

pipeOutA3 : okPipeOut port map (ok1 => ok1, ok2 => ok2,ep_addr => x"a3", ep_datain => epA3pipe, ep_read => epA3read);
Code language: PHP (php)

okBTPipeIn

The Block-Throttled Pipe In module is similar to the okPipeIn module, but adds two signals, EP_BLOCKSTROBE and EP_READY to handle block-level negotiation for data transfer.  The host is still master, but the FPGA controls EP_READY.  When EP_READY is asserted, the host is free to transmit a full block of data.  When EP_READY is deasserted, the host will not transmit to the module.

EP_READY could, for example, be tied to a level indicator on a FIFO.  When the FIFO has a full block of space available, it will assert EP_READY signifying that it can accept a full block transfer.

SIGNALDIRECTIONDESCRIPTION
EP_ADDR[7:0]InputEndpoint address.
EP_DATAOUT[15:0]OutputPipe data output.
EP_WRITEOutputActive-high write signal.  Data should be captured when this signal is asserted.
EP_BLOCKSTROBEOutputActive-high block strobe.  This is asserted for one cycle just before a block of data is written.
EP_READYInputActive-high ready signal.  Logic should assert this signal when it is prepared to receive a full block of data.

VERILOG INSTANTIATION

okBTPipeIn pipeIn9C (.ok1(ok1), .ok2(ok2).ep_addr(8'h9c), .ep_dataout(ep9Cpipe), .ep_write(ep9Cwrite),.ep_blockstrobe(ep9Cstrobe), .ep_ready(ep9cready));

VHDL INSTANTIATION

pipeIn9C : okBTPipeIn port map (ok1 => ok1, ok2 => ok2,ep_addr => x"9c", ep_dataout => ep9Cpipe, ep_write => ep9Cwrite,ep_blockstrobe => ep9Cstrobe, ep_ready => ep9cready);
Code language: PHP (php)

okBTPipeOut

The Block-Throttled Pipe Out module is similar to the okPipeOut module, but adds two signals, EP_BLOCKSTROBE and EP_READY to handle block-level negotiation for data transfer.  The host is still master, but the FPGA controls EP_READY.  When EP_READY is asserted, the host is free to read a full block of data.  When EP_READY is deasserted, the host will not read from the module.

EP_READY could, for example, be tied to a level indicator on a FIFO.  When the FIFO has a full block of data available, it will assert EP_READY signifying that a full block may be read from the FIFO.

SIGNALDIRECTIONDESCRIPTION
EP_ADDR[7:0]InputEndpoint address.
EP_DATAIN[15:0]InputPipe data input.
EP_READOutputActive-high read signal.  Data must be provided in the cycle following as assertion of this signal.
EP_BLOCKSTROBEOutputActive-high block strobe.  This is asserted for one cycle just before a block of data is read.
EP_READYInputActive-high ready signal.  Logic should assert this signal when it is prepared to transmit a full block of data.

VERILOG INSTANTIATION

okBTPipeOut pipeOutA3 (.ok1(ok1), .ok2(ok2).ep_addr(8'ha3), .ep_datain(epA3pipe), .ep_read(epA3read),.ep_blockstrobe(epA3strobe), .ep_ready(epA3ready));

VHDL INSTANTIATION

pipeOutA3 : okBTPipeOut port map (ok1 => ok1, ok2 => ok2,ep_addr => x"a3", ep_datain => epA3pipe, ep_read => epA3read,ep_blockstrobe => epA3strobe, ep_ready => epA3ready);
Code language: PHP (php)