Design overview
The Spartan 3E Starter Kit
has an Ethernet port, but, unlike
the Altera DE2, the chip associated with this port does not implement
an Ethernet
controller, it only implements the PHY i.e. the physical transceiver
layer. This means that in order to send and receive packets over this
interface, we need an Ethernet controller. In this design, we use an
open core Ethernet controller from Opencores. A host module
demonstrates the use of the Ethernet controller; it
receives packets and loops them back out without modification.
Supporting
documentation
The chip manufacturer and part number is SMSC LAN83C185 and
its datasheet can be found here.
The Ethernet controller from Opencores comes with enough documentation
to use the core without having to look at the Verilog code too
often. There is in particular a specification document and a design
document.
Open Core Ethernet
Controller
The controller presents three interfaces:
- An interface to the PHY
- An interface to external memory where the packets will be
stored
- A user interface that allows the set-up of
the rx/tx buffer descriptors and the read/write of the various registers
The PHY interface is straightforward and there is nothing to do there
except
convert the tristate i/o into two distinct wires.
The controller
uses the external memory interface to read and write packets. The user
controls the
addresses by setting up the appropriate pointers in the buffer
descriptors.
This interface is a standard Wishbone interface. Obviously the
controller is a master (DMA) and the memory is a slave.
The
third interface can be conceptually divided into two different parts.
One is composed of the registers and the other is composed of the
buffer descriptors. The registers allow control of the ethernet
controller, such as setting the modes, the mac address, etc. The buffer
descriptors allow the user to control the receiving and sending of
packets and where in the external memory the packets are stored. Buffer
descriptors are either transmit or receive. They are 8-bytes long; the
first 4-bytes contain the status/control of the packet and the last
4-bytes contain the external memory address of the buffer where the
packet is stored. The interface is a standard Wishbone interface.
Obviously, this interface is a slave, and the host is the master.
Design
Here is the design diagram:
The top level module,
eth_loopback,
instantiates the host, the memory and the wishbone arbiter.
We choose the DDR SDRAM as
external memory, and for this we re-use
the
Xilinx MIG2.0 controller. The
main change here is that we need to add a module to convert
from the Wishbone to the MIG2.0 proprietary interface. The
module that provides this conversion
is
memory_wb_to_mig.
Also note that the MIG2.0-generated constraint file will
cause a problem as generated because the IO standard of the net is
not declared. Be sure to change the line:
NET "cntrl0_rst_dqs_div" LOC = P13 ;
to
NET "cntrl0_rst_dqs_div" LOC = P13 | IOSTANDARD = LVCMOS33 ;
To interconnect and arbitrate the two masters and
two slaves, we
use
eth_cop, a simple
arbiter provided with the test bench of the
Ethernet core. The module needs very slight modifications
in order for it to be synthetizable with XST and this also
impacts some of the constants in
the
defines
files. Also note that the define
MEM_BASE that is specific to the ethernet
cop needs to be renamed because it
conflicts with a MIG2.0
define. The arbitration provided
by
eth_cop is based
on the address values:
- 0x0000-0x0050: Registers (slave 1)
- 0x0400-0x05ff: Tx buffer descriptors (slave 1)
- 0x0600-0x07ff: Rx buffer descriptors (slave 1)
- 0x2000-0x32000: DDR SDRAM (slave 2)
Host
The host
module
loopback_controller reads
incoming packets and sends them back out without
modification. The loopback algorithm is straightforward:
initialize mode register
forever
initialize one rx buffer descriptor
wait until packet received in corresponding buffer descriptor
initialize tx buffer descriptor w/ same address as rx buffer and same length
endforever
The default parameters are used for all
registers except the mode register. The mode register needs its tx and
rx bits set in order to enable receive and transmit.
Buffer descriptors are composed of a pointer and of control/status
bits. The pointer is simply the DDR SDRAM address of the packet data.
Some control/status bits are determined by the user, for
example the
CRC bit in the tx buffer descriptor tells the Ethernet core to
calculate and add the CRC before sending the packet and some
control/status bits are determined by the Ethernet core, for example tx
or rx errors will be indicated to the user. One
particularly important control/status bit is the enable bit.
In a rx
buffer descriptor an enable bit set to 1 indicates to the core that it
can write the buffer descriptor and its associated buffer for packet
reception. Once the packet is received, the core resets the enable bit,
and the user can read the received packet and its status. The tx buffer
descriptors contain a similar enable bit. The user sets it to tell the
core to send a packet. Once sent, the core resets this bit indicating
that the packet was sent (or at least that there was an attempt to send
it).
Using the design
- Generate DDR SDRAM Xilinx MIG 2.0 controller files and
remove the testbench: refer to this design for further details.
- Unpack the ethernet core files.
- Unpack the files provided here, overwriting - when needed -
the ethernet core files.
- Append the contents of the ucf file to the ucf file
generated by the MIG2.0. Modify the net "cntrl0_rst_dqs_div" as
indicated above.
- Create a new project with all these files.
Design files
spartan_ethernet.zip