I'm trying to send data from a FPGA to the Ethernet Mac port of a SoC which has the stmmac Synopsys IP.

enter image description here

I'm using the MII protocol at 25MHz for 100Mb/s (4-bit per clock cycle).

I'm sending the following fake ethernet frame:

FF FF FF FF FF FF       Destination Mac (broadcast)
58 00 E3 5B E8 41       Source Mac
00 2E                   Type with size (46=0x2E)
01 02 03 ... 44 45 46   Packet
CF C7 1F CC             FCS

The whole frame is valid and checked at http://packetor.com. The FCS is correct.

FF FF FF FF FF FF 58 00 E3 5B E8 41 00 2E 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 CF C7 1F CC

My FPGA code looks like this:

reg [20:0] count;
reg ctl;
reg [3:0] d;

wire clk;
wire clk90;
pll pll_inst(
    .CLKI   (oscInternal),
    .CLKOP  (clk), //25MHz
    .CLKOS  (clk90) //25MHz shifted phase 90 degrees

//Packet is 8+6+6+2+46+4=72 bytes long, so 576 bits.
wire [575:0]val = 576'h55555555555555D5FFFFFFFFFFFF5800E35BE841002E01020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546CFC71FCC;

always @(posedge clk) begin
    if (count < 72 * 2) begin
        ctl <= 1;
        if (count[0] == 0)
            d <= val >> (576 - 8 - 4 * count);
            d <= val >> (576 - 4 * count);
    end else begin
        d <= 0;
        ctl <= 0;
    count <= count + 1;

assign rxd0 = d[1];
assign rxd1 = d[0];
assign rxd2 = d[2];
assign rxd3 = d[3];
assign rxctl = ctl;
assign rxclk = clk90;

I send 4-bit by 4-bit, first the lower 4 bits then the higher 4 bits of each byte. This is done at each clock cycle.

The rxclock is shifted of 90 degrees so that data is valid when the 25MHz rx clock is rising up.

I have checked on a digital analyzer and it looks good, similar to the traffic sent by a Realtek PHY.

In the kernel DTS, I have:

phy-mode = "mii";
fixed-link {
    speed = <100>;

When I boot, the kernel is correctly setup with the stmmac Mac. The kernel driver is here:


In dmesg, I see eth0 up and configured at 100Mb/s. ifconfig eth0 up is good.

I can send traffic via a Realtek PHY in a similar setup and it's received by the kernel.

But I don't see anything when I'm sending through my FPGA. Is there anything I'm missing or doing wrong?


1 Answer 1


First, what interface are you using? You said MII, but MII uses tx_en/tx_er or rx_dv/rx_er instead of tx_ctl/rx_ctl. Unless you're actually using RGMII, which muxes those two into one signal on opposite clock edges, with er inverted to reduce the number of transitions.

Second, this could be a problem:

assign rxd0 = d[1];
assign rxd1 = d[0];
assign rxd2 = d[2];
assign rxd3 = d[3];

But presumably the MAC should still count dropped packets. Although perhaps not if the switched bits screw up detection of the start of the frame.

Also, assuming you're using RGMII, that interface can use the data signals to transfer status information between frames. See the RGMII spec. The MAC may be looking at this status information, so you should could try generating that. Looks like you might want to set the data at idle to 4'b1011, to indicate full duplex link, 25 MHz clock, link up.

  • \$\begingroup\$ This is super useful! I have fixed the bit inversion (typo). I thought that RGMII and MII were identical. I have only one ctl pin so I'm using RGMII in the dts now. Still there is no received or dropped packets reported by ifconfig eth0. \$\endgroup\$ Aug 25, 2020 at 22:02
  • \$\begingroup\$ Well, in that case I'm out of ideas. Have you tried connecting the FPGA to the Realtek PHY to see if you can send packets that way as another sanity check? \$\endgroup\$ Aug 25, 2020 at 22:42
  • \$\begingroup\$ You already found two bugs. Thank you for your help. \$\endgroup\$ Aug 26, 2020 at 3:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.