When the tool calculates the X value for different phase widths, we
get rounding errors for every width in the interval [8;24].
Depending on the width thess errors cause overflows or smaller amplitudes
of the sine waves.
The error is not linear nor proportional with the phase. To fix the issue
a simple aproximation was chosen.
Perform the shifting operation before addition/subtraction in a
rotation stage. In the previous method, the result of the arithmetic
operation was shifted and the outcome was presented to the next stage.
In this way, data connections will be reduced between pipeline stages
Add parameters:
- to select the sine generator (polynomial/CORDIC)
- to select the CORDIC data width(default 16)
Suppress the warnings generated when the DDS is disabled.
https://en.wikipedia.org/wiki/CORDIC
Configurable in/out data width (14,16,18,20);
The HDL implementation requires pipelines, resulting in a
data_width + 2 clock cycles delay between the phase input data and the
sine data. For this reason, a ddata (delay data) was propagated through
the pipeline stages to help in future use scenarios
Some FMC boards do utilize more than one transceiver quad but do not
necessarily use all transceivers in a quad. On such board is the
AD9694-500EBZ. Which uses two transceivers each in two adjacent quads.
This board can not be supported by instantiating a util_adxcvr with only 4
lanes. Since those 4 lanes would be packed into the same quad. Instead it
it is necessary to instantiate a util_adxcvr with 6 lanes. 4 lanes for the
first quad and 2 for the second.
To still to be able to connect such a util_adxcvr to a link layer with only
4 lanes allow to specify sparse lane mappings. A sparse mapping can have
less lanes than the util_adxcvr and some lanes will be left unconnected.
For example for the AD9694-500EBZ the lane mapping looks like the following:
ad_xcvrcon util_ad9694_xcvr axi_ad9694_xcvr ad9694_jesd {0 1 4 5} rx_device_clk
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Sometimes the output clock of the transceiver should not be used for the
device clock.
E.g. for deterministic latency with no uncertainty the device clock needs
to be sourced directly from a clock or transceiver reference clock input
pin.
Add an option to the ad_xcvrcon command to specify the device clock.
In case the same device clock is used for multiple JESD204 links, e.g. a TX
and a RX link only one reset generator is created.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Typically only one of the character error conditions is true at a time. And
even if multiple errors were present at the same time we'd only want to
count one error per character.
For each character track whether at least one of the monitored error
conditions is true. Then count the number of characters for which at least
one error condition occurred. And finally add that sum to the total numbers
of errors.
This results in a slightly better utilization.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
When the link is explicitly disabled through the control interface reset
the error statistics counter.
There is usually little benefit to preserving until after the link has been
disabled. If software is interested in the values it can read them before
disabling the link. Having them reset makes the behavior consistent with
all other internal state of the jesd204 RX peripheral, which is reset when
the link is disabled.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
In MM2S applications like video DMA it is useful to mark the end of the stream
with the TLAST.
The change enables the generation of the TLAST on the last beat of the
last row of the 2d transfer.
The index on MSB of addresses was set to 31,
but the width of address in the axi_dmac depends on a parameter.
The mismatch causes issues in the Xilinx simulator which does not extends the
narrower width signal with zeros, instead the wider signal gets 'Z' on its MSBs.
When the address was incremented with the stride it became 'X' due the uninitialized
MSBs.
Vivado recognises .h files as C header files,
the expected extension for Verilog Header is .vh
This causes issues in simulating block designs since these files
won't be exported for the simulation even if they are
part of the simulation fileset.
When creating a block design targeted for simulation, in the testbench
it is useful to know the parameters of the sub components (e.g DMAC)
Xilinx's way to pass the parameters to the testbench in case of it's AXI
verification IP is through package files. We will do the same for the DMAC.
The package file can be generated from template files (ttcl).
These will be added only to the simulation file set of the project and
won't affect synthesis.
This change adds a diagnostic interface to the DMAC core.
The interface exposes internal information about the core,
information which can't be exposed through AXI registers
due the latency and update rate.
Such information is the fullness of the internal buffer.
For this is exposed in bursts and is driven from the destination
clock domain, as this is reflected in its name.
The signal has a fixed size and is dimensioned by
taking in account the supported maximum number of bursts of 128.
This change adds the TLAST signal to the AXI streaming interface
of the source side for Intel targets.
Xilinx based designs already have this since the tlast is part of the
interface definition.
In order to make the signal optional and let the tool connect a
default value to the it, the USE_TLAST_SRC/DEST parameter is
added to the configuration UI. This conditions the tlast port on
the interface of the DMAC.
Xilinx handles the optional signals much better so the parameter
is not required there.
In its current implementation the DMAC requires that the length of a
transfer is aligned to the widest interface. E.g. if the widest interface
is 128 bits wide the length of the transfer needs to be a multiple of 16
bytes.
If the requested length is not aligned to the interface width it will be
rounded up.
This works fine as long as both interfaces have the same width. If they
have different widths it is possible that the length is rounded up to
different values on the source and destination side. In that case the DMA
will deadlock because the transfer lengths don't match and either not enough
of too much data is delivered from the source to the destination side.
Currently it is up to software to make sure that such an invalid
configuration is not possible.
Also enforce this requirement in the DMAC itself by setting the LSBs of the
transfer length to a fixed 1 so that the length is always aligned to the
widest interface.
Software can also use this to discover the length alignment requirement, by
first writing a zero to the length register and then reading the register
back. The LSBs of the read back value will be non-zero indicating the
alignment requirement.
In a similar way the stride needs to be aligned to the width of its
respective interface, so the generated addresses stay aligned. Enforce this
in the same way by keeping the LSBs cleared.
Increment the minor version number to reflect these changes.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The transfer abort logic in the src_axi_stream module is making some
assumptions about the internal timings of the data mover module.
Move this logic inside the data mover module. This will make it easier to
update the internal logic without having to update other modules.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The only two users of the data mover module both implement the same
sync-transfer-start logic. Move this into the data mover module to avoid
the duplicated code.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
With the recent rework there is now a fair amount of dead code in the
datamover module that is no longer used. Remove it.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Data is gated on the source side interface and not let into the pipeline if
there is no space available inside the store and forward memory.
This means whenever data is let into the pipeline space is available and
backpressure wont be asserted. Remove the backpressure signals altogether
to simplify the design.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently the source side of the DMAC can issue requests for up to
2*FIFO_SIZE-1 bursts even though there is only room for FIFO_SIZE bursts in
the store and forward memory.
This can problematic for memory mapped buses. If the data is not read fast
enough from the DMAC back-pressure will propagate through the whole system
memory subsystem and can cause significant performance penalty or even a
deadlock halting the whole system.
To avoid this make sure that not more that than what fits into the
store-and-forward memory is requested by throttling the request ID based
on how much room is available in the memory.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The second destination side register slice was put in place to provide
additional slack on some of the datapath control signals. It looks as if
this is no longer required for the latest version of the DMA controller.
All timing paths have sufficient margin.
So remove this extra slice register which just takes up resources and adds
pipeline latency.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently both the source side and the destination side interfaces employ a
beat counter to identify the last beat in a burst.
The burst memory already has an internal last signal on the destination
side. Exporting it allows the destination side interfaces to use it instead
of having to generate their own signal. This allows to eliminate the beat
counters on the destination side and simplify the data path logic.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently the destination side request ID is synchronized response ID from
the source side. This signal is effectively the same as the synchronized
src ID inside the burst memory. The only difference is that they might not
increment in the exact same clock cycle.
Exporting the request ID from the burst memory means we can remove the extra
synchronizer block.
This has the added bonus that the request ID will increment in the same
clock cycle as when the data becomes available from the memory.
This means we can assume that when there is a outstanding burst request
indicated via the ID that data is available from the memory and vice versa
when data is available from the memory that there is a outstanding burst
request.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently the DMAC uses a simple FIFO as the store-and-forward buffer. The
FIFO handshaking is beat based whereas the remainder of the DMAC is burst
based. This means that additional control signals have to be combined with
the FIFO handshaking signal to generate the external handshaking signals.
Re-work the store-and-forward buffer to utilize a BRAM that is subdivided
into N segments. Where N is the maximum number of bursts that can be stored
in the buffer and each segment has the size of the maximum burst length.
Each segment stores the data associated with one burst and even when the
burst is shorter than the maximum burst length the next burst will be
stored in the next segment.
The new store-and-forward buffer takes care of generating all the
handshaking signals. This means handshaking is generated in a central place
and does not have to be combined from multiple data-paths simplifying the
overall logic.
The new store-and-forward buffer also takes care of data width up- and
down-sizing in case that the source and sink modules have a different data
width. This tighter integration will allow future enhancements like using
asymmetric memory.
This re-work lays the foundation of future enhancements to the DMA like
support for un-aligned transfers and early transfer abort which would have
been much more difficult to implement with the previous architecture.
In addition it significantly reduces the resource utilization of the
store-and-forward buffer and allows for better timing due to reduced
combinatorial path lengths.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
There is an implicit dependency between the outgoing data stream and the
incoming response stream. The AXI specification requires that the
corresponding response is not sent before the last beat of data has been
received.
We can take advantage of this and remove the currently explicit dependency
between the data and response paths. This slightly simplifies the design.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
For the AXI streaming interfaces we need to make sure that the handshaking
rules for the external interface are met. Hence we can't just disable the
DMA and have to wait for any pending beats to complete.
For the FIFO interfaces on the other hand no such requirements exist. All
handshaking is for the internal pipeline which will be reset as a whole so
it is OK to violate the handshaking without causing any undefined behavior.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
For the memory-mapped AXI read interface the slave asserts rlast for the
last beat in a burst.
This means we don't have to count the number of beats to know when the
burst is completed but instead can use rlast. This slightly reduces the
amount of resources needed for the MM-AXI source module and given that the
beat_counter is often the bottleneck timing wise this should also improve
the timing.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>