The main issue with that is that the PIO does not have decent support for external clock inputs, let alone any kind of clock recovery. It can easily send a 100MHz signal, but it can't reliably receive one.
The PIO allows for single-cycle or dual-cycle data output, which essentially just pulls bits from a FIFO and puts them on some pins. The "side-set pin" makes it really easy to generate a clock signal as well. If the target devices samples on rising edge, it becomes essentially "output data, clock low; nop, clock high; implicit repeat" or even "output data; implicit repeat" if the target can do its own clock recovery or uses DDR. This is great, because you can output a lot of data at quite high speeds.
But the opposite is a lot harder. The PIO has no native clock support, so you're left simulating it yourself with a multi-instruction operation. If you need even as little as two instructions to receive a bit, that 133MHz MCU clock already limits you to a 66MHz signal!
In theory you could use an external clock input - but those pins are limited to 50MHz. You could also feed the external clock into the main oscillator input - but that breaks a bunch of other functionality, especially if the external clock isn't reliable.
Oversampling isn't an option either: you'd have to read the pins at 4x the signal frequency (limiting you to 33MHz) and dedicate a lot of computing resources to that.
In other words, high-speed input is only really an option if you don't care about synchronization, such as a free-running logic analyzer. But bitbanging 100BASE-T Ethernet? Don't count on it. Even the 2-bit-wide 50MHz RMII interface has proven to be quite challenging.
Thanks for the insights. I've only written one PIO program, and it's for a DHT22 sensor. I divided the clock down to 1 MHz so I could count microseconds. Really, CPU bit-banging would have worked fine at those speeds.
Now that I think about it more, you're right. Best case scenario for reading a bit would be to wait for the pin to go high/low, then push the corresponding bit into the input shift register, and have that automatically flush to DMA every 32 bits, say. Can't do better than some fraction of the clock speed because of the multiple instructions needed.
The PIO allows for single-cycle or dual-cycle data output, which essentially just pulls bits from a FIFO and puts them on some pins. The "side-set pin" makes it really easy to generate a clock signal as well. If the target devices samples on rising edge, it becomes essentially "output data, clock low; nop, clock high; implicit repeat" or even "output data; implicit repeat" if the target can do its own clock recovery or uses DDR. This is great, because you can output a lot of data at quite high speeds.
But the opposite is a lot harder. The PIO has no native clock support, so you're left simulating it yourself with a multi-instruction operation. If you need even as little as two instructions to receive a bit, that 133MHz MCU clock already limits you to a 66MHz signal! In theory you could use an external clock input - but those pins are limited to 50MHz. You could also feed the external clock into the main oscillator input - but that breaks a bunch of other functionality, especially if the external clock isn't reliable. Oversampling isn't an option either: you'd have to read the pins at 4x the signal frequency (limiting you to 33MHz) and dedicate a lot of computing resources to that.
In other words, high-speed input is only really an option if you don't care about synchronization, such as a free-running logic analyzer. But bitbanging 100BASE-T Ethernet? Don't count on it. Even the 2-bit-wide 50MHz RMII interface has proven to be quite challenging.