Commit Graph

89 Commits

Author SHA1 Message Date
Sean Anderson 2c2527e8d9 axis_replay_buffer: Fix slave handshaking
Handshaking happens on the rising edge based on the current values of
ready/valid. Fix the current (incorrect) logic. Additionally, modify the
testbench to properly stimulate AXI stream cores. This will catch
several handshaking failures fixed in previous commits.

Fixes: 52325f2 ("Add AXI stream replay buffer")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-05 14:30:27 -05:00
Sean Anderson 58cebe5ac2 uart_tx: Fix AXIS handshaking
AXI stream data is transferred based on the current values of the signals,
not the previous ones. This will cause problems if the other end isn't
valid all the time. Fix this, and amend the testbench to test it.

Fixes: e44d381 ("Add UART transmit module")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-05 14:30:07 -05:00
Sean Anderson 1bbb6d7f41 axis_wb_bridge: Fix wishbone handshaking
The wishbone transfer logic is incorrect. We need to use signals from the
current cycle, not the previous one.

Fixes: 7514231 ("Add AXIS-Wishbone bridge")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-05 14:30:05 -05:00
Sean Anderson 601cccd3dc uart_rx: Add state machine debug
Add a textual description of the state machine for easier debugging.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-04 16:43:32 -05:00
Sean Anderson 067029ad3b uart_rx: Fix incorrect handshaking
AXI stream is transferred exactly on the rising edge of the clock. Use
the current value of the signals for this, instead of past values.
Simulate a slower slave to ensure this is tested.

Fixes: a549fca ("Add UART receive module")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-04 16:43:22 -05:00
Sean Anderson 10a4199381 axis_wb_bridge: Fix AXIS master
The AXI stream master doesn't cope with slaves that aren't ready all the
time. There are two separate issues: first, the data was only valid for one
cycle. Second, the handshake logic was incorrect. Rectify these, and modify
the testbench to test for this condition.

Fixes: 7514231 ("Add AXIS-Wishbone bridge")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-04 14:32:04 -05:00
Sean Anderson d2b4351899 axis_wb_bridge: Use DATA_WIDTH parameter
This was defined but left unused. Use it for the width of various
registers.

Fixes: 7514231 ("Add AXIS-Wishbone bridge")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-04 14:30:26 -05:00
Sean Anderson d44c5b257e uart_tx: Add reset
Add a reset to match uart_rx.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-04 12:37:54 -05:00
Sean Anderson f09b89adeb phy_internal: Disable coltest without wishbone
When the wishbone management interface is disabled, disable coltest.

Fixes: b351beb ("Add hub")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-04 12:29:46 -05:00
Sean Anderson 3b49fedb6d mdio_regs: Simplify conditions
Instead of duplicating the cyc/stb condition everywhere, just reuse the
one from ack.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-04 12:28:34 -05:00
Sean Anderson 75142311f2 Add AXIS-Wishbone bridge
This adds the core of the UART-Wishbone bridge. The protocol has
a variable-length address phase to help reduce overhead. Multiple
in-flight commands are not supported, although this could be resolved
with some FIFOs.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-03-01 20:14:22 -05:00
Sean Anderson a549fca957 Add UART receive module
Add the recieve half of the UART. It's more or less the inverse of the
transmit half, except we manage the state explicitly. I originally did
this in hopes that yosys would recode the FSM, but it doesn't like the
subtraction in the D* states. I left in the async reset anyway since it
reduces the LUT count.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-28 23:50:36 -05:00
Sean Anderson e44d381c20 Add UART transmit module
I join everyone and their mother in creating my own UART. 8n1 only, and 2
baud rates. Accepts AXI-stream.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-28 22:26:05 -05:00
Sean Anderson 45b134b1b2 Add examples
This adds an example of how to integrate the hub into a design. For the
moment, wishbone is disabled, but I plan to add a uart bridge in the
future.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-20 23:34:10 -05:00
Sean Anderson f82fd2cac3 hub/phy_core: Export some status signals
Export some status signals which can be used for LEDs. Hopefully this
will deliver an authentic blinkenlights experience.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-20 23:34:10 -05:00
Sean Anderson b351beb9a0 Add hub
This adds a basic hub wrapper module which incorperates the core
introduced in b68e131 ("Add a basic hub"). For each port, it
instantiates a phy (itself using a phy_internal wrapper) and an elastic
buffer. A WISHBONE parameter is used to control whether to instantiate a
wishbone interface. When disabled, we just respond to any request with
err. I've ommitted a separate testbench for phy_internal, since it is
much easier to create a smoke test using the hub interface.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-20 23:34:10 -05:00
Sean Anderson cc29d2050c pmd_dp83223_rx: Don't use SB_IO for signal_detect
The flip-flops internal to the SB_IO can't have initial values and
can't be reset. So before the first clock the data out will be X. This
results in a simulation-synthesis mismatch, as sd_delay will be wrong
for one clock cycle. Fix this by removing the SB_IO cell, as the timing
of this signal isn't critical.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-20 18:39:58 -05:00
Sean Anderson 7c9ac42988 Add wishbone mux
This adds a simple wishbone mux. The idea is that each slave gets its
own address bit. This lends itself to extemely simple address decoding,
but uses up address space quickly. In theory, we could also give larger
addres space to some slaves, but currently lower bits have priority. The
testbench is also very simple. Since everything is combinatorial, we can
determine the outputs from the inputs exactly.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-18 22:48:36 -05:00
Sean Anderson 3b9efe2211 mii_elastic_buffer: Don't use memory access hack on valid/err
We can already probe the valid/err signals, so we don't need to
explicitly access them.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-18 22:48:36 -05:00
Sean Anderson eb8d854476 Silence warnings when converting memories to registers
There are several places where memories are used for parametrization
purposes, but I intend them to be synthesized to registers. Silence
warnings about them by explicitly annotating these variables.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-18 22:48:36 -05:00
Sean Anderson d98e7b3adf Add LED blinker
This module will make it easier to observe internal signals which would
otherwise be too short to see, or would trigger too fast to distinguish.
Continuous triggered will cause blinking, so signals which are expected
to be high for a while (e.g. level-based and not edge-based) should not
use this module.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-18 22:48:36 -05:00
Sean Anderson 16b639aad2 Add MII elastic buffer
In order to move data between MIIs without implementing a MAC, we need
some kind of elastic buffer to bring the data into the transmit "clock
(enable) domain." Implement one. It's based on a classic shift-register
FIFO, with the main difference being the MII interfaces and the
elasticity (achieved by delaying asserting RX_DV until we reach the
WATERMARK). We use a register-based buffer because we only need to deal
with an under-/over-flow of 5 or so clocks for a 2000-byte packet. The
per-stage resource increase works out to 6 FFs and 1 LUT, which is
pretty much optimal.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-02-12 19:53:44 -05:00
Sean Anderson b68e1312c4 Add a basic hub
This adds a basic clause 27 repeater (hub), mostly for test purposes.
It's effectively just the state machine in figure 27-4 and nothing else
(e.g. no partitioning or jabber detection). This is surprisingly simple.

Unfortunately, yosys doesn't allow memories in port declarations, even
for systemverilog. This complicates the implementation and testbench,
since we have to do the slicing ourselves. This is particularly awful
for the testbench, since

	module.signal[0].value != module.signal.value[0]

and module.signal can't be indexed by slices, and module.signal.value is
big endian (ugh ugh ugh). There is no clean solution here.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-21 17:39:25 -05:00
Sean Anderson 798968d3d6 axis_mii_tx: Add support for half duplex
This adds support for half-duplex. This is mostly done by predicating
col and crs on half_duplex. In one place we need to go to IPG_LATE
directly (although we could go to IPG_LATE like FCS with no loss of
standard compliance).

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-14 00:08:38 -05:00
Sean Anderson 43612337e4 axis_mii_tx: Don't reset mii_txd
It's not valid anyway.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-13 23:35:23 -05:00
Sean Anderson 11bb9651c0 Use separate process for non-resetting registers
Including registers which are not reset in an asynchronous reset process
causes active-low clock-enable flip-flops to be synthesized. This is an
unusual configuration, incurs overhead, and isn't what we wanted to do
anyway. Use a separate process.

While we're at it, sort the bottom half of the if to match the top.

Fixes: 19f2f65 ("axis_mii_tx: Add reset")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-13 23:13:12 -05:00
Sean Anderson 536bdd86bd axis_mii_tx: Delay error handling by one cycle
The 2 ns delay when reading from a BRAM makes it hard to close timing,
since buf_err affects the state machine. Address this by not acting on
errors for a clock cycle. We will output bad data for a cycle, but we
are going to corrupt the FCS anyway so it doesn't matter. We also have
to check for errors in the PAD/FCS states, to ensure they don't slip
past.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-11 17:32:50 -05:00
Sean Anderson aba4fb10c2 axis_mii_tx: Simplify backoff
We only care about backoff when state=BACKOFF. We can simplify the
calculation by defaulting to loading lfsr into backoff, and special
casing things for state=BACKOFF.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-11 00:52:51 -05:00
Sean Anderson 19f2f656cd axis_mii_tx: Add reset
Yosys doesn't optimize FSMs without resets. Add one so ours gets
optimized.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-10 23:56:04 -05:00
Sean Anderson 23913a6b77 axis_mii_tx: Remove some initial values
These signals are initialized (usually by IPG) before they are used.
Remove their initialization.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-10 00:24:44 -05:00
Sean Anderson 0495ae377c Add TX MAC (most of it)
This adds the transmit half of a MAC, supporting 100M and half-duplex.
It's roughly analogous to the axis_(x)gmii_tx modules in Alex
Forencich's ethernet repo. I've taken the approach of moving all state
into the state variable. All decisions are made once and have a
different state for each path. For example, instead of checking against
a "bytes_sent" variable to determine what to do on collision, we have a
different state for each set of actions.

This whole module is heinously complex, especially because of the many
corner cases caused by the spec. I have probably not tested it nearly
enough, but the basics of sending packets have mostly had the bugs wrung
out.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-09 21:05:31 -05:00
Sean Anderson 83216ea1e9 scramble: Fix initial lfsr value
I was missing a bit.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-09 20:51:59 -05:00
Sean Anderson 5b3c350581 pmd: Initialize sd_delay
Although the least-significant bit of sd_delay is driven by an SB_IO (if
we are synthesizing), the other bits need to be initialized.

Fixes: d8ce165 ("pmd: Delay signal_status/detect until data is valid")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-09 20:31:39 -05:00
Sean Anderson acfd5f62d2 replay_buffer: Fix s_ptr passing m_ptr
The condition for determining s_axis_ready only looks at whether we are
currently full, not whether we will be full on the next cycle (which is
what matters). Make it take into account whether we are going to
increment s_ptr during the current cycle. Also increase the ratio to
ensure we trigger this case, as a ration of 2 doesn't make the slave
slow enough to catch this.

Fixes: 52325f2 ("Add AXI stream replay buffer")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2023-01-02 18:47:07 -05:00
Sean Anderson 91ab3b40ce replay_buffer: Fix
If the lower bits of m_ptr is the same as s_ptr when we get s_axis_last
(that is, we are full), then we will immediately end (since m_ptr will
equal last_ptr). Fix this by including all of s_ptr in last_ptr.

Fixes: 52325f2 ("Add AXI stream replay buffer")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-12-24 23:46:35 -05:00
Sean Anderson 040016bd44 phy_core: Simplify collision logic
This mildly simplifies the collision logic.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-30 18:14:23 -05:00
Sean Anderson 2eac757fd7 Add DP83223-based PMD
This adds the integrated PMD module to be used with the DP83223. It
contains NRZI en/decoding as well as the I/O interfaces. The rx I/O was
added a while back, and the tx is just the I/O cell.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-30 18:14:23 -05:00
Sean Anderson 3b836d3ad0 nrzi_decode: Add reset input
Most other modules in the recieve path are reset when signal_status goes
low. This one didn't, and it was difficult to test because of this. In
particular, we need to ensure that this module behaves correctly when
switching between different bitstreams (such as for loopback).

While implementing this, I found some bugs in the way that nrzi_valid
was handled: it wasn't saved from when the transfer actually happened,
and the data wasn't qualified properly.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-30 18:14:23 -05:00
Sean Anderson 52325f241b Add AXI stream replay buffer
This implements an AXI stream buffer which allows replaying of the first
portion of each packet. The intent is to simplify the implementation of
CSMA/CD. This requires keeping 56 bytes of data to "replay" (slot time
minus the preamble). After these bytes are transmitted, we can only get
late collisions.

We always read from the buffer, as this simplifies the implementation
compared to some kind of hybrid fifo/skid buffer approach. The primary
design problem faced is in determining when it's OK to overwrite the
first byte in the packet. A naïve approach might be to allow overwriting
whenever the slave reads the last byte. However, in the case of a
54-byte packet, we will still need to allow replaying at this point (in
case there is a collision on the last byte). We can't just wait for
m_axis_ready to go high, because that would violate the AXI stream
protocol. To solve this, the slave must assert the done signal when it
is finished with the packet.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-30 18:14:23 -05:00
Sean Anderson f6f3f024e4 Add phy_core
This module integrates the PCS with the descrambler, implements the PMA
(which is just the link monitor), and implements loopback and coltest
functions. This is more of the PCS/PMA, but the descrambler is
technically part of the PMD, so it's the "core" instead.

We deviate from the standard in one important way: the link doesn't come
up until the descambler is locked. I think this makes sense, since if
the descrambler isn't locked, then the incoming data will be gibberish.
I suspect this isn't part of the standard because the descrambler
doesn't have a locked output in X3.263, so IEEE would have had to
specify it.

Loopback is actually implemented in the PMD, but it modifies the
behavior in several places. It disables collisions (unless
coltest is enabled). Additionally, we need to force the link up (to
avoid the lengthy stabilization timer), but ensure it is down for at
least once cycle (to ensure the descrambler desynchronizes).

On the test side, we just go through the "happy path," as many of the
edge conditions are tested for in the submodule tests. Several of those
tests are modified so that their helper functions can be reused in this
test. In particular, the rx path is now async so that we can feed it
rx_data.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 12:37:18 -04:00
Sean Anderson 02069bceee pcs: Add false_carrier signal
This adds an explicit false carrier signal. Trying to determine this
condition the MDIO signals is tricky because BAD_SSD can last over
several cycles of CE. To make things easier, add a signal which is high
only once per event.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 12:37:18 -04:00
Sean Anderson ece7d6c619 descramble: Pass through scrambled_valid
Even when signal_status is low, we should still generate data. This
keeps the PCS processes moving along.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-05 11:54:39 -04:00
Sean Anderson db30c5f8ba mdio_regs: Add register to enable test modes
This adds a register allowing us to control the test modes of the
descrambler and link monitor.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-02 17:44:37 -04:00
Sean Anderson 7d35e07401 mdio_regs: Add support for counters
This adds support for counters for interesting conditions (disconnects,
PMD phase wraparounds, errors, etc). All the counters are 15 bits
instead of 16, because 16-bit counters have an fmax of 110MHz or so. All
the counters live behind a condition because they ~double the number of
resources used.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-02 17:37:34 -04:00
Sean Anderson ec08287853 scrambler: Fix wrone assignment type
This process uses the wrong assignment type. Fix it.

Fixes: 12a4678 ("Add (de)scrambling support")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-11-02 00:16:43 -04:00
Sean Anderson 63006ca9c0 pmd_dp83223: Delay signal_status by an additional clock
When increasing the delay for the recieved data, I forgot to increase
the delay for the signal status as well. Fix this.

Fixes: c02d3f3 ("pmd_io: Calculate wraparound based on state and not state_next")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-10-30 22:02:32 -04:00
Sean Anderson cf0aed4980 pmd_io: Rename to pmd_dp83223_rx
This better reflects that this is an interface intended to be used with
the DP83223. While we're at it, refactor the module to just handle the
the recieve portion.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-10-30 22:01:35 -04:00
Sean Anderson 494ef2a2a9 pcs: Split into rx/tx
For easier integration, split the PCS into its rx and tx components.
This was already done on the module level, but now they live in separate
files.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-10-30 21:32:02 -04:00
Sean Anderson c02d3f3ad0 pmd_io: Calculate wraparound based on state and not state_next
Basing the wraparound calculation on state_next is causing problems for
timing. Do it with the state calculations instead. We need to add
another cycle of latency to make this work, since we can't output the
data correctly without knowing the wraparound.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-10-30 20:58:18 -04:00
Sean Anderson 2d8caf575d pmd_io: Use single-ended inputs
These inputs were incorrectly marked as LVDS, which was causing problems
for placement. Make them single-ended.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
2022-10-30 20:57:04 -04:00