The AGPL was mostly a placeholder until I determined a better license to
use. TBH I wasn't expecting that anyone would find this repo.
Closes: #1
Signed-off-by: Sean Anderson <seanga2@gmail.com>
We can't actually accept data during reset, so don't assert ready.
Modify the testbench to try to send data while the core is reset, so we
can verify that it doesn't get accepted.
Fixes: 52325f2 ("Add AXI stream replay buffer")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
The value of the lfsr does not matter, as long as it keeps ticking. Use
initial instead of resetting it.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
The OUI in the PHY ID is "bit-reversed," AKA each byte is bit reversed,
but the overall order is the same. This is a bit more complex than I
initially thought. Fix the mapping, and use a non-zero OUI for testing.
Fixes: d9602b6 ("Add MII management functions")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
Document how the LFSR initial values are generated. Also fix several
off-by-one errors (where the documented cycles was not quite right).
Signed-off-by: Sean Anderson <seanga2@gmail.com>
Add an option to register the wishbone busses post-mux. This can help
achieve timing, since the phys are often in different parts of the FPGA.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
If the input and output clock enables are exactly aligned, the elastic
buffer can overflow (as it waits for 2 entries before offering, and
there's a cycle of latency). Increase the size so we don't run into that
situation.
Fixes: b351beb ("Add hub")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
This module registers all signals on a wishbone bus. This increases
latency/decreases throughput, but the wishbone cores here are just for
management, so that's not really critical.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
It's convenient to be able to adjust this parameter if the counters ever
end up on the critical path. Support adjusting it from hub.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
The counters in this module end up on the critical path a lot. The
counters themselves take 3-4 ns to compute, but routing the increment
signal to the counter eats up a lot of slack. Register the increment signal
for a clock to let it cross the FPGA without affecting the counter timing.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
ack/err can only be combinatorial if data_read is also combinatorial.
I suspect doing that will kill my Fmax, so register ack/err.
Fixes: d9602b6 ("Add MII management functions")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
Add a reset synchronizer to ensure synchronous reset release. There is
also a glitch filter to reject spurious resets. It will reject pulses
shorter than 5 ns (or around 1.25 ns per LUT).
Signed-off-by: Sean Anderson <seanga2@gmail.com>
Add a basic bridge for debugging. It's around 50% efficient, but this
could be increased to 66% with the addition of some FIFOs. The limiting
factor is the constant overhead of the request/status bytes. If we used
a wider bus, we could get better efficiency.
Signed-off-by: Sean Anderson <seanga2@gmail.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>