The previous mechanism was "probing" the DMAs for valid data. Better said,
each interpolation channel enabled it's DMA until a valid data was received,
then it disabled the DMA read and waited for the adjacent channel(DMA) to
receive a valid data. Only when for both channels had valid data on the
DMAs interfaces was the transmission started. This added an undesired and
redundant complexity to the interpolation channels. Furthermore, for continuous
transmission, using the above mechanism lead to a fixed phase(sample)
shift between the two channels at each start.
By using the streaming mechanism the interface is simplified and the
above problems are solved.
For Intel projects:
In cases where the clock of source synchronous interface is not routed
through a clock capable pin the DPA receive mode can't be used. Instead
the clock will be routed through a clock buffer from an IO to the clock
tree and from there to the IOPLL.
implemented mux for temp reading either from internal or external
source; updated regmap; added param to identify source for temp
information; updated tacho measurements; added AVG_POW param used
for tacho measuremet average useful for simulations; defaults for
tacho measurements changed to params and added registers; added
prescaler for fsm control, FSM updated; changed register write
process; connected INTERNAL_SYSMONE to regmap, value can now be
read by software;
parameters with same names were duplicated with transceiver specific
names due different default values.
This does not scales very well.
Use same name for the parameters as for other parameters and do the
default value handling in the IP configuration layer.
In order to help timing closure on multi SLR FPGAs add a pipeline stage
between the link layer and physical layer. This will add a fixed amount
of delay to the overall latency.
Bus sizes often depend on parameters. In such cases the physical indexes
of the interfaces from the multi bus must be calculated based on parameters.
For each interface expose the formula that calculates the indexes to the
block design.
* jesd204b: add bonding clocks feature (fix for some routing issues)
* intel/adi_jesd204: bonding clock feature invisible in QSYS GUI if number of lanes is less than 6
* intel/adi_jesd204: clock network option renamed according to intel documentation
* intel/adi_jesd204: Hide BONDING_CLOCKS_EN parameter in RX mode
Co-authored-by: István Csomortáni <Csomi@users.noreply.github.com>
When using a non-maximum sampling rate the data is captured earlier by two
samples.
After the initial trigger jitter fix, a low latency/utilization was
desired(one sample delay for the trigger detection). After adding the
instrument trigger an equal latency between ADC and LA was required, hence the
need for a two sample delay on the trigger path. The delay was implemented
as two clock cycle delays not two sample delays.
This commit fixes this issue and offers a more robust design.
A trigger jitter was added by fix on the external trigger input. It
manifests at input sampling frequencies lower than the maximum frequency.
Added the required reset and CE(valid) signal to the last output
stages of the trigger to obtain the desired functionality for all
sampling rates.
The extra delay was added on the trigger and data paths to compensate
for the logic analyzer changes.
The extra delay will be also seen on the m2k daisy chain. The
delay between devices will be increased from 3 to 4 samples delay.
Fix external trigger for low sampling rates.
Because the external trigger can be a short pulse at high decimation rates
there is a high chance that the pulse will be missed.
xsim does not like if a register or wire is used before their
definition. Make sure the every register and wire is defined before it's
used the first time.
In Subclass 1 mode, we need to use a separate clock (device clock) to
drive the link and transport layer of the interface. Implement the
required infrastructure for this scenario.
The clock domain crossing will be done in by the TX|RX_FIFO in the PCS.
In Subclass 1 mode an external device clock (core clock) is used,
instead of the PCS output clock, to drive the link and transport layer.
Define an additional parameter, which can be used to enable clock input
port for the PHY module, which can be used as rx|tx_coreclkin source.
This commit reverts part of the changes done in the following commit:
- ff50963c7f -
"axi_ad9361- altera/xilinx reconcile- may be broken- do not use"
The above mentioned commit introduced latency variations on the Rx path
at different sample rates, or within the same sample rate after sample
rate changes. The variation is caused by multiple positions of the frame
detection combined with a free running toggle (rx_valid) that is not synchronized
with the actual samples.
Having a single frame detection position eliminates the latency
variation.
When having multiple 936x in parallel, this change enables the use of source
synchronous received clock from the master as sampling clock for other slaves.
This will eliminate skew between the interfaces since the data delays
are going to be tuned against the master clock after a multi-chip
synchronization (MCS) is done. This eliminates the clock crossing from
the slave to master domain inside the FPGA.
Sync the two valid signals to keep a fixed phase relationship between
the Rx ant Tx channels, this way avoiding +/- 1 sample differences
on the Tx-Rx latency between consecutive transfers.
The pulse period had a fixed value. Therefore, in order to be able
to configure it from the software, a 32b register pulse_period_reg
was added in axi_spi_engine. Also, to generate the pulse, the
output register pulse_gen_loadc was added.
- Add parameter for input data delay time to easily match the one of the
adc_trigger.
- Change the trigger delay path to match between the internal and
external(adc_trigger delays).
The ready signal of the SYNC interface should be always 1'b1,
regardless of ASYNC_SPI_VALUE.
Drive the ready with one in both branches of the ASYNC_SPI_CLK
generate block.
Currently trigger out pin is hold for 1ms in the next translation(t+1)
state(0 or 1). But not in the state that follows (t+2). This commit
fixes this issue and simplifies the logic.
The previous channel sync mechanism was simply holding the transmission by
pulling down the dma_rd_en of the two DMAs for each channel(set reg 0x50). After a
period of time (that will take the two DMAs to have the data ready to move)
the dma_rd_en was set for both channels, resulting in a synchronized start.
This mechanism is valid when the two channels are streaming the same
type of data (constant, waveform, buffer or math) at close frequencies.
Streaming 10MHz on a channel and 100KHz on the second one will result
in different interpolation factors being used for the two channels.
The interpolation counter runs only when the dma_transfer_suspended(reg 0x50)
is cleared. Because of this, different delays are added by the interpolation
counter one DMA with continuous dma_rd_en will have data earlier than the
one with dma_rd_en controlled by the interpolation counter. Furthermore,
because the interpolation counter value is not reset at each
dma_transfer_suspended, the phase shift between the 2 channels will
differ at each start of transmission.
To make the transfer start synced immune to the above irregularities a
sync_transfer_start register was added (bit 1 of the 0x50 reg).
When this bit is set and the bit 0(dma_transfer_suspended) is toggled,
the interpolation counters are reset. Each channel enables it's DMA until
valid data is received, then it waits for the adjacent channel to get valid data.
This mechanism will be simplified in a future update by using a streaming
interface between the axi_dac_interpolate and the DMAs that does not require
the probing of the DMA.
The decimation module controls the valid signal. The whole triggering mechanism
is active only when the valid signal is active.
In the case of low sampling rates, the valid signal is active once every
n clock cycles. If an external trigger condition is fulfilled and the data valid
signal is low at the time, that trigger will be ignored by the DMA.
To solve this issue, the trigger is held high until the valid is asserted.
And it stays high for at least one clock cycle.
The trigger signal that goes to the DMA(fifo_wr_sync) does not pass through
the variable fifo, for this reason, a 3 clock cycles delay is required, to
keep in sync the data with the trigger.
On the other hand, to be able to cascade the axi_logic_analyzer with
axi_adc_trigger, there should be small delays on the trigger path, for this
reason the trigger_out_adc was created.
Remove the extra delays on the trigger_i(external trigger pins).
- Add embedded trigger as an option. The use of the embedded trigger as an
option in the data stream is done for further processing, keeping the data
synchronized with the trigger.
When instrument (module) trigger is desired (logic_analyzer - adc_trigger),
a small propagation time is required, hence the need to remove the
util_extract(trigger extract) module from the data path.
- Add more options for the IO triggering. This will open the door for multiple
M2k synchronization(triggering).
trigger_o mux:
1 - trigger flag (from regmap)
2 - external pin trigger (Ti)
3 - external pin trigger (To)
4 - internal adc trigger
5 - logic analyzer trigger
The signal passed to trigger_o must not be delayed, but the new value has to be
kept for a short period, 1ms (100000 clock cycles), to reduce switch noises in
the system.
The axi_adc_trigger handles 3 output triggers:
- trigger_o - external trigger (1 clock cycle delay)
- trigger_out - signals on dmac/fifo_wr_sync the start of a new transfer.
A variable fifo depth is present in the data path, which delays the data
arriving at the DMA with 3 clock cycles. By coincidence, the external trigger
is synchronized and detected on 3 clock cycles. To get a maximum optimization
the trigger_out will be delayed with 3 clock cycles for internal triggers and
directly forwarded in the case of an external trigger.
- trigger_out_la (cascade trigger for logic_analyzer - m2k example)
Because the trigger_out_la must have a small delay, to get a realible
instrument triggering mechanism, a 1 delay clock cycle must be added on the
trigger paths, to avoid creating a closed combinatorial loop.
Increase pcore version. The major version 3 is used to describe the instrument
trigger updates.
This commit was created by squashing the following commits, these
messages were kept just for sake of history:
ad9694_500ebz: Mirror the SPI interface to FMCB
ad9694_500ebz: Set transceiver reference clock to 250
ad9694_500ebz: Allow to configure number of lanes, number of converters
and sample rate
axi_ad9694: Fix number of lanes, it must be 2
ad9694_500ebz: Update the mirrored spi pin assignments
ad9694_500ebz: Gate SPI MISO signals based on chip-select
ad9694_500ebz: Set channel pack sample width
ad9694_500ebz: Change reference clock location
ad9694_500ebz: Remove transceiver memory map arbitration
ad9694_500ebz: Ensure ADC FIFO DMA_DATA_WIDTH is not larger ADC_DATA_WIDTH
ad9694_500ebz: Adjust breakout board pin locations
ad_fmclidar1_ebz: Rename the ad9694_500ebz project
ad_fmclidar1_ebz: Fix lane mapping
ad_fmclidar1_ebz: Delete deprecated files
ad_fmclidar1_ebz: Integrate the axi_laser_driver into the design
ad_fmclidar1_ebz: OTW is an active low signal
ad_fmclidar1_ebz: zc706: Fix iic_dac signals assignment
ad_fmclidar1_ebz: Switch to util_adcfifo
ad_fmclidar1_ebz: Enable synced capture for the fifo
ad_fmclidar1_ebz/zc706: Enable CAPTURE_TILL_FULL
ad_fmclidar1_ebz/zc706: Reduce FIFO size to 2kB
ad_fmclidar1_ebz: Laser driver runs on ADC's core clock
ad_fmclidar1_ebz_bd: Delete the FIFO instance
Because the DMA transfers are going to be relatively small (< 2kbyte),
the DMA can handle the data rate, even when the frequency of the laser
driver pulse is set to its maximum value. (200 kHz)
The synchronization will be done by connecting the generated pulse to
the DMA's SYNC input. Although, to support 2 or 1 channel scenarios, we
need to use the util_axis_syncgen module to make sure that the DMA
catches the pulse, in cases when the pulse width is too narrow. (SYNC is
captures when valid and ready is asserted)
Also we have to reset the cpack IP before each pulse, to keep the DMA buffer's
relative starting point in time fixed, when only 2 or 1 channel is
active.
The module can receive a synchronous or asynchronous pulse with an arbitrary
width and generate a SYNC signal for the DMA Source AXI Streaming interface.
This way we can synchronize the DMA transfers to an external
pulse/signal.
The laser driver contains the axi_pulse_gen's IP and an additional
register map which controls/monitor the laser driver enable control line
and the over temperature warning line (OTW).
It also contains an interrupt logic, which allows to generate an
interrupt in function of the generated pulse or incoming OTW signal.
The IPs register maps looks as follow:
0x00 - axi_pulse_gen register map
0x80 - axi_laser_driver register map
0x80 - DRIVER_ENABLE
0x84 - DRIVER_OTW
0x88 - EXT_CLK_COUNTER
0xA0 - IRQ_MASK
0xA4 - IRQ_SOURCE
0xA8 - IRQ_PENDING
0xAC - SEQUENCER_CONTROL
0 - SEQUENCER_ENABLE
1 - AUTO_SEQUENCER_ENABLED
0xB0 - SEQUENCER_SYNC_OFFSET
0xB4 - AUTO_SEQUENCE
[ 1: 0] - CHANNEL_SEL_0
[ 5: 4] - CHANNEL_SEL_1
[ 9: 8] - CHANNEL_SEL_2
[13:12] - CHANNEL_SEL_3
0xB8 - MANUAL_SEQUENCE
[ 1: 0] - MANUAL_CHANNEL_SEL
Current interrupt sources scheme is:
- bit 0 : pulse (triggered by the level of the pulse)
- bit 1 : OTW_N enter (triggered by positive edge of the OTW_N)
- bit 2 : OTW_N exit (triggered by the level of the pulse)
Generate a reset signal before the pulse which can be used to reset
various IP's of the data path (eg. pack/cpack). This can help to clear out the
internal buffers and registers of these IP, starting clean at the moment when
the actual pulse arrives.
The sequencer has an auto and a manual mode, and can be set to custom
sequences of the TIA channel selection lines sate.
The sequencer in auto mode is synchronized to the pulse, it will change
its state before a generated pulse which will drive the lasers. The
offset between the sequencer beat and the laser driver pulse can be
modified through an AXI register.
- add missing false paths
- change the bus skew constraint to a false path, for some reason the
tool does not change the path's requirement after a set_bus_skew
constraint
Our internal repository was changed from phdl to ghdl. Update the
adi_env.tcl scripts and other scripts, which depends on the $ad_ghdl_dir
variable. This way the tools will see all the internal IPs too.
Add additional synchronization FIFOs to several interfaces of the
axi_spi_engine module, to prevent metastability and timing issues in
case when the system clock and the SPI clock are asynchronous.
There are devices where the SDO default state, between transactions, is
not GND, rather VCC.
Define a parameter, which can be used to set the default state of the
SDO line.
Move the subtraction outside of the always block. In this way we're not adding
an additional delay element on to the output of the differentiator,
which brakes the transfer function of the filter.
This patch will fix the following warning:
[Synth 8-689] width (16) of port connection 'up_axi_awaddr'
does not match port width (12) of module 'up_axi'
Vivado propagates and auto derives the clocks, however if multiple
instances of this components are used the names of the propagated clock
change while the constraint file has fixed name which will match only
the clocks from the first instance letting the second instance of the
clock div without exception.
Use missing MIMO_ENABLE parameter, which will insert
and additional de-skew logic to prevent timing issues coming from
the clock skew differences of two or multiple AD9361.
Define a MIMO_ENABLE parameter for the core, which will insert
and additional de-skew logic to prevent timing issues coming from
the clock skew differences of two or multiple AD9361.
Let the measured transfer length to be cleared at the end of each
transfer, other case in cyclic mode the counter will overflow and will
not present any useful information.
Once xfer_request is set the DMA must accept samples in the same clock
cycle if the fifo_wr_en signal is asserted.
If the req_valid asserts faster than the ID gets synchronized over the
the xfer request asserts without being ready to accept data.
This can lead to overflow assertion when using a FIFO like interface.
This patch addresses the following issue:
In case of transfers with multiple segments, if TLAST asserts on the last
beat of a non-last segment while more descriptors are queued up,
the completions for the queued segments may be missed causing timeout in
processes that wait for transfer completions.
This patch addresses the following issue:
In 2D mode when consecutive partial transfers occur, and the latter is
very short, will interfere with the completion mechanism of the first
transfer leading to uncompleted segments and unreported partial
transfers.
The tb_base.v verilog files does not contain a full module definition,
just some plain test code. In general the files is sourced inside the
test bench main module. As is, defining a timescale in these files will
generate an error, because timescale directive can not be inside a
module.
Delete all the timescale directive from these files.
When only one converter is used there is no need for concatenation and
slicer cores. In that case the TPL will connect to port 0 from the
application layer.
These parameters must be overwritten when the link is at 15Gbps.
The parameters have a GTY4_ prefix since the same parameters are shared
between GTY4 and GTH4 having different default values.
The interrupt controller from Microblaze based projects requires that
all its inputs have attributes which define the sensitivity of the
interrupt line. Other case it defaults to EDGE_RISING which is not the
case for DMAC, leading to incorrect interrupt reporting and handling in
case of such projects.
Out of Context constraints are needed for timing driven synthesis as for
avoiding critical warnings due clock queries.
The memory from the FIFO is inferred in different ways for high clock
speeds. Assume the highest frequency for all projects.
Fix library makefiles dep list using generic vendor info reg
Combine adi_int_bd_tcl with adi_auto_fill_bd_tcl procedure.
This change will simplify the process of generating makefiles for each library.
Removing the bd.tcl script from the adi_ip_files list will remove it from the
make dependency list.
Having a bd.tcl script in every IP is redundant.
adi_ip.tcl:
- add adi_init_bd_tcl - creates a blanch bd.tcl and a
parameters temporary_case_dependencies.mk when compiling an IP.
Its main purpose is to generate the bd.tcl, which will be included in
the IP's file-set.
- adi_auto_fill_bd_tcl will populate the empty bd.tcl based on the
top IP parameters and the presence of these parameters in
auto_set_param_list and auto_set_param_list_overwritable lists.
This task can not be performed by the first described procedure since
the file-set is not yet defined.
adi_xilinx_device_info_enc.tcl:
Split auto_set_param_list_overwritable from auto_set_param_list. As
the name states, some of the parameters are overwritable, this will help
when generating the bd.tcl script.
library.mk:
Include the temporary_case_dependencies.mk if it exists in the
IP root folder. The mentioned *.mk file contains non generic
dependencies for makefiles like targets to clean.
Common basic steps:
- Include/create infrastructure:
* Intel:
- require quartus::device package
- set_module_property VALIDATION_CALLBACK info_param_validate
* Xilinx
- add bd.tcl, containing init{} procedure. The init procedure will be
called when the IP will be instantiated into the block design.
- add to the xilinx_blockdiagram file group the bd.tcl and common_bd.tcl
- create GUI files
- add parameters in *_ip.tcl and *_hw.tcl (adi_add_auto_fpga_spec_params)
- add/propagate the info parameters through the IP verilog files
axi_clkgen
util_adxcvr
ad_ip_jesd204_tpl_adc
ad_ip_jesd204_tpl_dac
axi_ad5766
axi_ad6676
axi_ad9122
axi_ad9144
axi_ad9152
axi_ad9162
axi_ad9250
axi_ad9265
axi_ad9680
axi_ad9361
axi_ad9371
axi_adrv9009
axi_ad9739a
axi_ad9434
axi_ad9467
axi_ad9684
axi_ad9963
axi_ad9625
axi_ad9671
axi_hdmi_tx
axi_fmcadc5_sync
Xilinx:
When calling adi_auto_fpga_spec_params in the x_ip.tcl, parameters like
- FPGA_TECHNOLOGY
- FPGA_FAMILY
- SPEED_GRADE
- DEV_PACKAGE
- XCVR_TYPE
- FPGA_VOLTAGE
will be automatically detected and constrained to predefined pairs of values
from adi_xilinx_device_info_env.tcl
The parameters specified in the blobk diagram of the IP(bd.tcl), will be
automatically assign when the IP is added to a block design.
The "adi_auto_assign_device_spec $cellpath" is called in the init
hook (bd.tcl).
https://www.xilinx.com/products/technology/high-speed-serial.html
Intel:
Info parameters are set in the VALIDATION_CALLBACK according to
adi_intel_device_info_env.tcl
Fix the following warning:
WARNING: [Synth 8-2611] redeclaration of ANSI port up_es_reset is not allowed
Also make sure, that in all configurations, the register has a diver.
Add support for 8 bit resolution for the transport layer.
Fix parameter BITS_PER_SAMPLES propagation to all the internal modules, in
several cases this variable was hard coded to 16.
The axi_pulse_gen is a generic PWM generator, which can be configured
through an AXI Memory Mapped interface.
The current register map look like follows:
0x00 - VERSION
0x04 - ID
0x08 - SCRATCH
0x0C - IDENTIFICATION - 0x504c5347 which stands for 'PLSG' in ASCII
0x10 - CONFIGURATION - contains reset and load bits
0x14 - PULSE_PERIOD
0x18 - PULSE_WIDTH
Also update all the other modules, which instantiate the util_pulse_gen.
To prevent the case, when after an invalid configuration, the generated
output PWM signal is constant HIGH, change the counter to a
down-counter. In this way the pulse will be placed at the end of the
PWM period, and if the configured width value is higher than the
configured period the output signal will be constant LOW.
Write code to pipeline data path for better DSP utilization on the
color space conversion.
In the old method the addition operations were performed outside the
DSPs
The FIFO functions in 'first fall through' mode, adjust the fifo level
generation so it take into account the valid data which sits on the bus,
waiting for ready, too.
Current implementation does not supports updated versions of Vivado
e.g. 2017.4.1 or 2018.2.1
This fix ignores the update number from the version checking.
Registers from this component can fit in the 2k address range.
Since Vivado's minimal address range is 4k, use that instead.
This will allow placing the independent TPLs to base addresses
that mach the addresses from the monolithic blocks ensuring no software
intervention.
The DMAC has the requirement that the length of the transfer is aligned to
the widest interface width. E.g. if the widest interface is 256 bit or 32
bytes the length of the transfer needs to be a multiple of 32.
This restriction can be relaxed for the memory mapped interfaces. This is
done by partially ignoring data of a beat from/to the MM interface.
For write access the stb bits are used to mask out bytes that do not
contain valid data.
For read access a full beat is read but part of the data is discarded. This
works fine as long as the read access is side effect free. I.e. this method
should not be used to access data from memory mapped peripherals like a
FIFO.
This means that for example the length alignment requirement of a DMA
configured for a 64-bit memory and a 16-bit streaming interface is now only
2 bytes instead of 8 bytes as before.
Note that the address alignment requirement is not affected by this. The
address still needs to be aligned to the width of the MM interface that it
belongs to.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
FPGAs support different widths for the read and write port of the block
SRAM cells. The DMAC can make use of this feature when the source and
destination interface have a different width to up-size/down-size the data
bus.
Using memory cells with asymmetric port width consumes the same amount of
SRAM cells, but allows to bypass the re-size blocks inside the DMAC that
are otherwise used for up- and down-sizing. This reduces overall resource
usage and can improve timing.
If the ratio between the destination and source port is too larger to be
handled by SRAM alone the SRAM block will be configured to do partial up-
or down-sizing and a resize block will be inserted to take care of the
remaining up-/down-sizing. E.g. if a 256-bit interface is connected to a
32-bit interface the SRAM will be used to do an initial resizing of 256 bit
to 64 bit and a resize block will be used to do the remaining resizing from
64 bit to 32 bit.
Currently this feature is disabled for Intel FPGAs since Quartus does not
properly infer a block RAM with different read and write port widths from
the current ad_asym_mem module. Once that has been resolved support for
asymmetric memories can also be enabled in the DMAC.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The handling of the src_data_valid_bytes signal and its related signal is
tightly coupled to the behavior of the resize_src module. The code that
handles it makes assumptions about the internal behavior of the resize_src
module.
Move the handling of the src_data_valid_bytes signal when upsizing the data
bus into the resize_src module so that all the code that is related is in
the same place and the code outside of the module does not have to care
about the internals.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The DMA_LENGTH_ALIGN LSBs of all length For the most part the tools are
able to deduce this using constant propagation.
But this propagation does not work across the asynchronous meta data FIFO
in the burst memory module.
Add a DMA_LENGTH_ALIGN parameter to the burst_memory module which is used
to explicitly keep the LSBs of length registers on the destination side
fixed at 1'b1. This reduces resource use and improves timing by allowing
better constant propagation and unused logic elimination.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This simplifies the burst length in the response manager significantly
while not costing much extra resources in the burst memory.
This change will also enable other future improvements.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
One of the major features of the DMAC is being able to handle non matching
interface widths for the destination and source side.
Currently the test benches only support the case where the width for the
source and the destination side are the same. Extend them so that it is
possible to also test and verify setups where the width is not the same.
To accomplish this each byte memory location is treated as if it contained
the lower 8 bytes of its address. And then the written/read data is
compared to the expected data based on that.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
On Arria10 there are 6 transceivers in a single bank. If more than 6
transceivers are used these will end up in multiple banks.
The ATX PLL can directly connect to the transceivers in the same bank
through the 1x clock network. To connect to transceivers in another bank it
has to go through a master clock generation block (MCGB) and the xN clock
network.
Add support for instantiating the MCGB if more than 6 lanes are used. In
this case the first 6 transceivers will still have a direct connection to
the PLL while all other transceivers will be clocked by the MCGB.
Note that this requires that the first 6 transceivers are all in the same
bank.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
All projects have been updated to use the new pack/unpack infrastructure.
The old util_cpack and util_upack cores are now unused an can be removed.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The util_cpack2 core is similar to the util_upack core. It packs, or
interleaves, a data from multiple ports into a single data. Ports can
optionally be enabled or disabled.
On the input side the cpack2 core uses a multi-port FIFO interface. There
is a single data write signal (fifo_wr_en) for all ports. But each port can
be individually enabled or disabled using the enable signals.
On the output side the cpack2 core uses a single port FIFO interface. When
data is available on the output interface the data write signal
(packed_fifo_wr_en). Data on the packed_fifo_wr_data signal is only valid
when packed_fifo_wr_en is asserted. At other times the content is
undefined. The cpack2 core offers no back-pressure. If data is not consumed
when it is made available it will be lost.
Data from the input ports is accumulated inside the cpack2 core and if
enough data is available to produce a full output vector the data is
forwarded.
This core is build using the common pack infrastructure. The core that is
specific to the cpack2 core is mainly only responsible for generating the
control signals for the external interfaces.
The core is accompanied by a test bench that verifies correct behavior for
all possible combinations of enable masks.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The util_upack2 core is similar to the util_upack core. It unpacks, or
deinterleaves, a data stream onto multiple ports.
The upack2 core uses a streaming AXI interface for its data source instead
of a FIFO interface like the upack core uses.
On the output side the upack2 core uses a multi-port FIFO interface. There
is a single data request signal (fifo_rd_en) for all ports. But each port
can be individually enabled or disabled using the enable signals.
This modified architecture allows the upack2 core to better generate the
valid and underflow control signals to indicate whether data is available
in a response to a data request.
If fifo_rd_en is asserted and data is available the fifo_rd_valid signal
are asserted in the following clock cycle. The enabled fifo_rd_data ports
will be contain valid data during the same clock cycle as fifo_rd_valid is
asserted. During other clock cycles the output data is undefined. On
disabled ports the data is always undefined.
If no data is available instead the fifo_rd_underflow signal is asserted in
the following clock cycle and the output of all fifo_rd_data ports is
undefined.
This core is build using the common pack infrastructure. The core that is
specific to the upack2 core is mainly only responsible for generating the
control signals for the external interfaces.
The core is accompanied by a test bench that verifies correct behavior for
all possible combinations of enable masks.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Pack and unpack operations are very similar in structure as such it makes
sense for pack and unpack core to share a common infrastructure.
The infrastructure introduced in this patch is based on a routing network
which can implement the pack and unpack operations and grows with a
complexity of N * log(N) where N is the number of channels times the number
of samples per channel that are process in parallel.
The network is constructed from a set of similar stages composed of either
2x2 or 4x4 switches. Control signals for the switches are fully registered
and are generated one cycle in advance.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Add support for Vivado's simulator. By default the run script is using
the Icarus simulator.
If the user want to switch to another simulator, it can be explicitly
specify the required simulator tool in the SIMULATOR variable.
Currently, beside Icarus, Modelsim (SIMULATOR="modelsim") and Vivado's
xsim (SIMULATOR="xsim") is supported.
For consistent simulation behavior it is recommended to annotate all source
files with a timescale. Add it to those where it is currently missing.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
By default inferred output reset signals have an active low polarity. The
axi_ad9361 rst output signal is active high though. Currently when
connecting it to a input reset with active high polarity will generate an
error in IPI.
Fix this by explicitly marking the polarity of the rst signal as active
high.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Replace the open-coded instances of a perfect shuffle in the DAC framer with
the new helper module.
Using the helper module gives well defined semantics and hopefully makes
the code easier to understand.
There are no changes in behavior.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The perfect shuffle is a common operation in data processing. Add a shared
module that implements this operation.
Having this in a shared module rather than open-coding every instance makes
sure that there are clear and well defined semantics associated with the
operation that are the same each time. This should ease review, maintenance and
understanding of the code.
The perfect shuffle splits the input vector into NUM_GROUPS groups and then
each group in WORDS_PER_GROUP. The output vector consists of
WORDS_PER_GROUP groups and each group has NUM_GROUPS words. The data is
remapped, so that the i-th word of the j-th word in the output vector is
the j-th word of the i-th group of the input vector.
The inverse operation of the perfect shuffle is the perfect shuffle with
both parameters swapped.
I.e. [perfect_suffle B A [perfect_shuffle A B data]] == data
Examples:
NUM_GROUPS = 2, WORDS_PER_GROUP = 4
[A B C D a b c d] => [A a B b C c D d]
NUM_GROUPS = 4, WORDS_PER_GROUP = 2
[A a B b C c D d] => [A B C D a b c d]
NUM_GROUPS = 3, WORDS_PER_GROUP = 2
[A B a b 1 2] => [A a 1 B b 2]
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The write logic (DMA side) has to be independent from the read logic (DAC side).
In general the FIFO is always ready for the DMA, and every DMA transaction will
interrupt the read-back process, and the module will stop sending data,
until the initialization is finished.
Bringing back the write address tot he DMA clock domain is totally
redundant, so delete it.
Expose the TX configurable driver ports, more specifically the
TX_DIFFCTRL, TX_POSTCURSORE and TX_PRECURSORE for software. This
provides a soft tunning capability of the transmit side of the
transceivers, in cases where the insertion loss of the channel is too
high or low, comparing to the default value supported by the default
configuration of the GTs.
You can find information about these configuration ports under the
section called 'TX Configurable Driver' in the GT transceivers user
guide. (UG476, UG576)
This commit does not contain any functional modification.
Because the wizard generates the attributes in binary, we should use
binary mode too, so we can compare different configurations more easily.
If the req_valid asserts faster than the ID gets synchronized over we
assert the xfer request without being ready to accept data.
This can lead to overflow assertion when using a FIFO like interface.
Data mover/ src axis changes
Request rewind ID if TLAST received during non-last burst
Consume (ignore) descriptors until last segment received
Block descriptors towards destination until last segment received
Request generator changes
Rewind the burst ID if rewind request received
Consume (ignore) descriptors until last segment received
If TLAST happened on last segment replay next transfer (in progress or
completed) with the adjusted ID
Create completion requests for ignored segments
Response generator changes
Track requests
Complete segments which got ignored
Length of partial transfers are stored in a queue for SW reads.
The presence of partial transfer is indicated by a status bit.
The reporting can be enabled by a control bit.
The progress of any transfer can be followed by a debug register.
Drive the descriptor from the source side to destination
so we can abort consecutive transfers in case TLAST asserts.
For AXIS count the length of the burst and pass that value to the
destination instead the programmed one. This is useful when the
streams aborts early by asserting the TLAST. We want to notify the
destination with the right number of beats received.
For FIFO source interface reuse the same logic due the small footprint
even if the stream does not got interrupted in that case.
For MM source interface wire the burst length from the request side to
destination.
The constraint for the synchronizer that synchronizes the sync_status
signal of the link only works correctly for the first link. For other links
no timing exception is applied, which leads to timing failures.
Fix this by using a wildcard constraint for the synchronizer reg number.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
If DDS_DW is equal to DDS_D_DW there is no signal truncation and
consequentially no rounding should be performed. But the check whether
rounding should be performed currently is for if DDS_DW is less or equal to
DDS_D_DW.
When both are equal C_T_WIDTH is 0. This results in the expression
'{(C_T_WIDTH){dds_data_int[DDS_D_DW-1]}};' being a 0 width signal. This is
not legal Verilog, but both the Intel and Xilinx tools seem to accept it
nevertheless.
But the iverilog simulation tools generates the following error:
ad_dds_2.v:102: error: Concatenation repeat may not be zero in this context.
Xilinx Vivado also generates the following warning:
WARNING: [Synth 8-693] zero replication count - replication ignored [ad_dds_2.v:102]
Change the condition so that truncation is only performed when DDS_DW is
less than DDS_D_DW. This fixes both the error and the warning.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The DISPLAY_NAME of a module is supposed to be a short human readable
description of the IP core.
Currently this is set to the name of the IP, which already has its own
property called NAME.
This causes Platform Designer to display the descriptive labels if the IP
core basically as "$ip_core_name ($ip_core_name)".
The value that all current user of ad_ip_create pass for the description
parameter matches this criteria (And not so much the requirements for the
actual DESCRIPTION property).
Change things, so that the DISPLAY_NAME property is set to what is
currently passed as the description parameter.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The Xilinx's reset interface expect that every reset have an associated
interface and clock signal. The tool will try to find its clock and interface,
and automatically associated clock signal to it.
The PLL resets are individual asynchronous resets. To simplify the design
and avoid invalid critical warnings all the reset interface inference
for the PLL resets were removed.
Most converters refer to their different operating modes as a "Mode X"
(where X is a number) in their datasheet. Each mode has a specific framer
configuration associated with it.
Provide a set of Platform Designer (previously known as Qsys) preset files
for each mode. This allows to quickly select a specific operating mode
without having to lookup the corresponding framer configuration from the
datasheet.
A preset can be selected either in the Platform Designer GUI or from a tcl
script using the apply_preset command. E.g.
add_instance ad9172_transport ad_ip_jesd204_tpl_dac
apply_preset ad9172_transport "AD9172 Mode 10"
The preset files are generated using the scripts/generate_presets.py
script and the scripts/modes.txt file.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
A converter typically only supports a specific subset of framer
configurations.
Add a configuration parameter to select a specific converter part number.
Based on the selected part a mode validation will be performed and if the
selected framer configuration is not supported by the part an error will be
generated.
This helps to catch invalid configurations early on rather than having to
first build the bitstream and then notice that it does not work.
When using "Generic" for the part configuration parameter no validation
will be done and any framer configuration can be selected.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The exact layout of the input data into the DAC transport layer core
depends on the framer configuration. The number of input channels is
always equal to the NUM_CHANNELS parameter, but the number of samples per
channel per beat depends on the ratio of number of lanes, number of
channels and bits per sample.
It is possible to compute this manually, but this might require in-depth
knowledge about how the JESD204 framer works. Add read-only parameters that
display the number of samples per channel per beat as well as the total
width of the channel data signal.
This information can also be queried in QSys scripts and used to
automatically configure the input pipeline. E.g. like the upack core:
set NUM_OF_CHANNELS [get_instance_parameter_value jesd204_transport NUM_CHANNELS]
set CHANNEL_DATA_WIDTH [get_instance_parameter_value jesd204_transport CHANNEL_DATA_WIDTH]
add_instance util_dac_upack util_upack
set_instance_parameter_values util_dac_upack [list \
CHANNEL_DATA_WIDTH $CHANNEL_DATA_WIDTH \
NUM_OF_CHANNELS $NUM_OF_CHANNELS \
]
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
For a specific set of L, M and NP framer configuration parameters there is
an infinite set of possible values for the S and F configuration parameters
as long as S and F are integer and the following relationship is met
S / F = (L * 8) / (M * NP)
Typically the preferred framer configuration is the one with the lowest
latency. The lowest latency is achieved when S is minimal.
Automatically compute and select this value for S instead of having the
user to manually provide a value.
Since some converters allow modes where S is not minimal provide a manual
overwrite to specify S manually in case somebody wants to use such a mode.
For completeness also add a read-only OCTETS_PER_FRAME (F) parameter that
can be used to verify and check which value for F was chosen.
There is no manual overwrite for F since if L, M, NP and S are set to a
fixed value there is only a single possible value for F, which is computed
automatically.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The ad_ip_jesd204_tpl_dac currently only supports JESD204 modes that have
both N and N' set to 16.
Newer DACs like the AD9172 support modes where N and N' are not equal to
16. Add support for these modes.
The width of the internal channel data path is set to N, only processing as
many bits as necessary. At the framer the data is up-sized to N' bits with
tail bits inserted as necessary. This data is then passed to the link
layer.
The width at the DMA interface is kept at 16 bits per sample regardless of
the configuration of either N or N'. This is done to keep the interface
consistent with the existing infrastructure it will connect to like upack
and DMA. The data is expected to the LSB aligned, the unused MSBs will be
ignored.
Same is true for the test-pattern data registers. These register keep their
existing 16-bit layout, but unused MSBs will be ignored by the core.
The PN generators are modified to create only N bits of data per sample.
Note that while the core can now support modes with N' = 12 there is still
the restriction that requires the number of frames per beat to be an even
number. Which means that not all modes with N' = 12 can be supported yet.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The current framer implementation is limited in that it only supports N'=16
and either S=1 or F=1.
Rework the framer implementation to be more flexible and support more
framer setting combinations.
The new framer implementation performs the mapping in two steps. First it
groups samples into frames, as there might be more than one frame per beat.
In the second step the frames are distributed onto the lanes.
Note that this still results in a single input bit being mapped onto a
single output bit and no combinatorial logic is involved. The two step
implementation just makes it (hopefully) easier to follow.
The only restriction that remains is that number of frames per beat must be
integer. This means that F must be either 1, 2 or 4. Supporting partial
frames would result in partial sample sets being consumed at the input,
which is not supported by input pipeline.
The new framer has provisions for handling values for the number of octets
per beat other than 4, but this is not exposed as a configuration option
yet since the link layer can only handle 4 octets per beat. Making the
octets per beat configurable is something for future iterations of the
core.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The ad_ip_jesd204_tpl_dac currently is only instantiated as a submodule by
other cores like the axi_ad9144 or axi_ad9152. These cores typically only
support one specific framer configuration.
In an effort to allow more framer configurations to be used the core is
re-worked, so it can be instantiated standalone.
As part of this effort provide GUI integration for Xilinx IP Integrator
where users can instantiate and configure the core.
For this group the configuration parameters by function, provide
descriptive label and a list of allowed values for parameter validation.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The ad_ip_jesd204_tpl_dac currently is only instantiated as a submodule by
other cores like the axi_ad9144 or axi_ad9152. These cores typically only
support one specific framer configuration.
In an effort to allow more framer configurations to be used the core is
re-worked, so it can be instantiated standalone.
As part of this effort provide GUI integration for Intel Platform Designer
(previously known as Qsys) where users can instantiate and configure the
core.
For this group the configuration parameters by function, provide
descriptive label and a list of allowed values for parameter validation.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The framer module is purely combinational at this point and the clk signal
is unused.
This is a leftover of commit commit 5af80e79b3 ("ad_ip_jesd204_tpl_dac:
Drop extra pipeline stage from the framer").
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Commit 5d044b9fd3 ("ad_ip_jesd204_tpl_dac: Share PN sequence generator
between all channels") add a new file to the ad_ip_jesd204_tpl_dac, but
neglected to update the hw.tcl for the axi_ad9144 and axi_ad9152 which use
this file.
The result is that Intel project using these cores currently do not build.
Fix it by adding the missing file to the file list.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Reduce the width of ID signals to avoid size mismatches in Arria 10 SoC
projects where the ID width of the hard IP is 4.
The width of ID that reaches the slave can be increased by the interconnect if
multiple masters access the slave so we end up with mismatches.
Since these signals are unused it is safe to reduce them to minimum width and
let the interconnect zero-extend them as required.
The buffers inside the interconnect are sized based on maximum burst sizes
the masters can produce.
For AXI4 the max burst size is 128 but for these projects for the
default burst size of 128 bytes the DMACs are creating only burst of 8 or
16 beats depending on the bus width (128bits and 64 bits respectively).
These burst sizes can fit in the AXI3 protocol where the max burst
length is 16. Therefore the interconnect will be reduced.
The observed reduction is around 4 Mb of block RAM per project.
Another benefit is a better timing closure,
since these buffers reside in the DDR3 clock domain.
This improvement will solve a couple of [DRC REQP-1839] warning:
"The RAMB36E1 has an input control pin * which is driven by a register * that has
an active asynchronous set or reset. This may cause corruption of the memory
contents and/or read values when the set/reset is asserted and is not analyzed
by the default static timing analysis. It is suggested to eliminate the use of
a set/reset to registers driving this RAMB pin or else use a synchronous reset
in which the assertion of the reset is timed by default."
The frame synchronization between axi_hdmi_tx and axi_dmac is based
on the DMA(2D streaming) last signal. The last signal will be used as
an end of frame signal marking the beginning of the future frame to be
transferred by the DMA.
Only after both HDMI and DMA are ready for a "new frame" data will be
requested from the DMA.
The datarate and CDC between the axi_dmac and axi_hdmi_tx cores
will be handled by axi_hdmi_tx's DMA interface based on a backpressure
mechanism.
Add a interface definition for the link interface that combines the valid,
ready and data signals into a AXI streaming interface.
This allows to connect the interface to the JESD204 link layer peripheral
in one go without having to manually connect each signal.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Some modes produce only one sample per channel per beat, e.g. when M=2*L.
In this case the pattern output needs to alternate between the two patterns
from beat to beat.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
All channels have a copy of the same logic to generate the PN sequences.
Sharing the PN sequence generator among all channels slightly reduces the
resource utilization of the core.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Only the N (where N is the size of the PN sequence) MSB bits of the reset
state of the PN generator should be set to 1. All other bits should be
initialized following the PN generator sequence.
Otherwise the first set of samples contain an incorrect PN sequence.
This does not increase the complexity of the PN generator, all reset values
are still constant.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
All the inputs to the framer are registered. And the framer itself does not
have any combinatorial logic, it just re-orders the wire numbering of the
individual bits.
Currently the framer module adds a output register stage, but since there
is no logic in the framer this just means that these registers are directly
connected to the output of the previous register stage.
Remove the extra pipeline register. This slightly reduces utilization and
pipeline delay of the core.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Remove unused register from the ad_ip_jesd204_tpl_dac_channel module.
Commit commit 92f0e809b5 ("jesd204/ad_ip_jesd204_tpl_dac: Updates for
ad_dds phase acc wrapper") removed all users of those registers.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>