Can not be multiple 'if' statements inside a generate block. If there are
multiple cases use if/esle statement, but always should be one single
if/else inside a generate.
When a mapping has multiple address segments we need to consider all of
them to calculate the required address width.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The address width needs to be large enough to be able to address the
largest possible address. This means the in addition to the address segment
range the specified offset also needs to be considered to calculate the
address width.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
up_rdata is qualified by the up_rack signal. There is no need to reset it
since by the time the signal is read the reset value has already been
overwritten anyway.
Also gate the up_rdata registers if no read operation is in progress. In
this case any changes would be ignored anyway.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The axi_adc_trigger does not use the full width of the AXI interface
address. It only responds to register access in the first 32 registers.
Reduce the size of the AXI address to 7 bit accordingly. This allows the
scripts to correctly infer the internal register map size which will cause
the interconnect to filter out access to these unused register.
This slightly reduces utilization by getting rid of some pipeline
registers.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The axi_adc_decimate does not use the full width of the AXI interface
address. It only responds to register access in the first 32 registers.
Reduce the size of the AXI address to 7 bit accordingly. This allows the
scripts to correctly infer the internal register map size which will cause
the interconnect to filter out access to these unused register.
This slightly reduces utilization by getting rid of some pipeline
registers.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The axi_dac_interpolate does not use the full width of the AXI interface
address. It only responds to register access in the first 32 registers.
Reduce the size of the AXI address to 7 bit accordingly. This allows the
scripts to correctly infer the internal register map size which will cause
the interconnect to filter out access to these unused register.
This slightly reduces utilization by getting rid of some pipeline
registers.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The axi_logic_analyzer does not use the full width of the AXI interface
address. It only responds to register access in the first 32 registers.
Reduce the size of the AXI address to 7 bit accordingly. This allows the
scripts to correctly infer the internal register map size which will cause
the interconnect to filter out access to these unused register.
This slightly reduces utilization by getting rid of some pipeline
registers.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The AXI DMAC peripheral only uses 11-bit of the register map interface
address. Reducing the signal width to this value allows the scripts to
correctly infer the size of the register map.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Not all peripherals need the full address space. To be able to infer the
size of the address space of a peripheral allow the size of the AXI address
signals to be configurable rather than hardcoding its width to 32 bit.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently the register map range of a peripheral is hardcoded to 64k. Not
all peripherals need that much space though and reducing the size of the
address can reduce the amount of logic required, both in the interconnect
as well as in the peripheral.
Let adi_ip_properties() infer the size of the register map from the number
of bits of the address when creating the register map.
For backwards compatibility limit the register map size to 64k since
currently peripherals have a address width of 32 bits, event if they use
less.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently the AXI address width of the DMA is always 32-bit. But not all
address spaces are so large that they require 32-bit to address all memory.
Extract the size of the address space that the DMA is connected too and
configure reduce the address size to the minimum required to address the
full address space.
This slightly reduces utilization.
If no mapped address space can be found the default of 32 bits is used for
the address.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The delay_clk is only used internally when the IODELAYs are enabled. This
means the port has no function when the IODELAYs are disabled so hide the
port in that case.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Typically when a port has a enablement dependency it also should have a
tie-off value to the port is connected to when disabled.
Make it possible to specify this tie-off value when calling
adi_set_ports_dependency().
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The output data mux is used to bypass the filter when it is not used. Which
setting is used for the mux depends on the 3-bit filter_mask signal.
Registering the control logic into a single bit signal reduces the amount
of routing resources required. Since changing the filter_mask settings is
asynchronous to the processing anyway the extra clock cycle delay
introduced by this change does not affect behaviour.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Move the processing pipeline of the axi_adc_decimate core to its own
sub-module. This makes it easier to simulate the processing independent of
the register map.
Also since the filter is two instances of the same logic, one for each
channel, let the new sub-module model one channel and instantiate it twice.
This allows to change the implementation without having to change the same
code twice.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The output data of the decimation block is 16-bit signed. Properly sign
extend the 12-bit input signal when the filter is bypassed.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The minimum number of bits required for the adders in a CIC filter depends
on the decimation rate. Higher decimation factors require more bits. This
means for a multirate filter the size of the logic structures is determined
by the highest supported rate.
The current implementation of the filter always uses all bits of the
structure to compute the results, that means even when running with the
lowest decimation factor all the bits that are required for the highest
decimation factor are used. This will work fine as additional bits do not
affect the output of the filter.
This patch implements dynamic partial gating of the filter structure based
on the selected decimation factor. Bits that are not required for a certain
rates are gated and the carry bits are masked from propagating through the
adder chain. This results in significant power savings at smaller
decimation factors.
This means that the filter itself is now using more power the higher the
decimation rate. But this is offset by the reduced data output rate running
subsequent processing stages at a lower rate and reducing power consumption
there. This results in a more or less flat power profile regardless of
decimation factor.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Allow to split a CIC int or comb block into multiple stages and be able to
dynamically gate some of the stages. Also prevent carry propagation in
gated stages to keep the adder output constant.
This is useful for multi-rate filter where not all bits are needed all the
time.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The minimum decimation rate of the CIC block is five, this means data
arrives at the FIR filter at most every five clock cycles. The decimation
rate of the filter is two so the filter produces an output at most every
ten clock cycles. This allows for ten clock cycles to compute the result.
The current implementation of the filter uses a fully pipelined
architecture with one multiplier for each coefficient. Which then do work
for one clock cycle and sit idle for the next nine clock cycles.
Rework the filter to be sequential reducing the number of required
multipliers to one. In addition exploit the symmetric structure of the
filter to make use of the preadder reducing the required multiply
operations by two.
This significantly reduces the logic utilization of the filter as well as
moderately reduces power consumption.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The minimum decimation of the CIC block is 5. This means new data arrives
at the comb stages at most every 5 clock cycles. Rather than letting the
logic sit idle during those 4 extra cycles use it to sequentially process
the comb stages of the filter. This reduces the logic utilization of the
filter by quite a bit.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The output data mux is used to bypass the filter when it is not used. Which
setting is used for the mux depends on the 3-bit filter_mask signal.
Registering the control logic into a single bit signal reduces the amount
of routing resources required. Since changing the filter_mask settings is
asynchronous to the processing anyway the extra clock cycle delay
introduced by this change does not affect behaviour.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Re-implement the CIC using the basic building blocks from the util_cic
library.
This new implementation is structurally equivalent to the previous version,
but will be used as a platform for implementing changes that will improve
area and power consumtion of the filter
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Move the processing pipeline of the axi_adc_decimate core to its own
sub-module. This makes it easier to simulate the processing independent of
the register map.
The debug registers are useful during development but are rarely used in a
production design. Add a option that allows to disable them, this reduces
the resource utilization of the DMAC.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently the BRAM and data registers in the util_axis_data are ungated
when the FIFO is ready to receive data. This good for high-performance
since it reduces the number of control signals. But it is bad from a power
point of view since it causes additional reads and writes.
Change the core gate the BRAM and data register if either the consumer is
not ready to accept data or the producer has no data to offer.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently the IDDRs are configured in SAME_EDGE_PIPELINED mode, but then
the negative data is delayed by an additional clock cycle. This is the same
behaviour as using the IDDR in SAME_EDGE mode.
Switching to SAME_EDGE mode removes extra pipelining registers while
maintaining the same behaviour.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The current implementation doesn't quite work right when the interface
clock is slower than the trigger clock and also causes timing issues.
Disable it temporarily until a proper CDC transfer is implemented.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The read and write interfaces of a AXI bus are independent other than that
they use the same clock. Yet when connecting a single read-only and a
single write-only interface to a Xilinx AXI interconnect it instantiates
arbitration logic between the two interfaces. This is dead logic and
unnecessarily utilizes the FPGAs resources.
Introduce a new helper module that takes a read-only and a write-only AXI
interface and combines them into a single read-write interface. The only
restriction here is that all three interfaces need to use the same clock.
This module is useful for systems which feature a read DMA and a write DMA.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The register read logic is not that complicated that it needs two extra
pipeline stages. It can easily be condensed into a single combinatorial and
still meet timing with large margins.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Disable registers in the register map which are not needed for this core.
This reduces the utilization of the core.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Not all peripherals use the GPIO register settings, but the registers still
take up a fair amount of space in the register map. Add options to allow to
disable them when not needed. This helps to reduce the utilization for
peripherals where these features are not needed.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Not all peripherals use the GPIO and START_CODE register settings, but the
registers still take up a fair amount of space in the register map. Add
options to allow to disable them when not needed. This helps to reduce the
utilization for peripherals where these features are not needed.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Depending on whether the core is configured for AXI4 or AXI3 mode the width
of the awlen/arlen signal is either 8 or 4 bit. At the moment this is only
considered in top-level module and all other modules use 8 bit internally.
This causes warnings about truncated signals in AXI3 mode, to resolve this
forward the width of the signal through the core.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Declaring local parameters in the module parameter list is not valid
verilog. For some reasons Vivado accepts it nevertheless so the code has
worked so far. But this is not true for other tools, so move the local
parameter definitions inside the module body.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
For experimentation, to solve a constraint scoping issue, split up the
ad_axi_ip_constraint file into separate constraints file, in function
of there parent module.
It seems that in the latest version a constant of "0" is no longer a valid
enablement dependency and "false" has be used instead.
Not setting the enablement dependency correctly results in the AXI port to
be assumed to be read-write rather than just read or write. This will
generate unnecessary logic for example in interconnects to which the DMA
controller is connected.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Xilinx recommends that all synchronizer flip-flops have
their ASYNC_REG property set to true in order to preserve the
synchronizer cells through any logic optimization during synthesis
and implementation.
Xilinx recommends that all synchronizer flip-flops have
their ASYNC_REG property set to true in order to preserve the
synchronizer cells through any logic optimization during synthesis
and implementation.
Add a human readable name and descriptor for the AXI DMAC core.This string
will appear in various places e.g. like the IP catalog. This is a purely
cosmetic change.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Add a register to the AXI DMAC register map which functions has a
identification register. The register contains the unique value of "DMAC"
(0x444d4143) and allows software to identify whether the peripheral mapped
at a certain address is an axi_dmac peripheral.
This is useful for detecting cases where the specified address contains an
error or is incorrect.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
- Change the clock and reset port name of the AXI slave interface
to s_axi_aclk and s_axi_aresetn. This way we can use the adi_ip_properties
process to infer the interface.
- Define an address space reference to the m_axi interface.
- Add a process, which automaticaly infer AXI memory mapped
interfaces (adi_ip_infer_mm_interfaces)
- Add missign line breaks to the 'set_propery supported_families'
command
- Fix the deletion of pre-infered memory maps
This patch is a complementary fix of 8b8c37 patch. And fix
all the 'infer interface' issues.
The adi_ip_infer_interfaces process was renamed to
adi_ip_infer_streaming_interfaces. Now the process just do
what its name suggest.
Affected cores were axi_dmac, axi_spdif_rx, axi_spdif_tx, axi_i2s_adi
and axi_usb_fx3. All these cores scripts were updated.
The SYSREF generator is using a simple free running counter,
which runs on the JESD204 core clock. The period can be
configured using a parameter, it must respect the constraints
defined by the JESD204 standard.
The generator can be enabled through a GPIO line.
The AXI Memory Map interface is infered in the adi_ip_properties process.
Infer it again in the adi_ip_infer_interfaces brakes the flow,
the tool will not find the cell's address segment, so there will not be
any address space assigned to the AXI interface.
Affected cores were axi_i2s_adi and axi_spdif_tx.
Start the counter_to_interrupt_cnt counter when the counter_to_interrupt
value is written to the register map. This gives applications better
control over when the counter starts counting.
Also start the counter_from_interrupt on the rising edge of the interrupt
signal to avoid bogus values.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The IRQ signal goes to a asynchronous domain. In order to avoid glitches to
be observed in that domain make sure that the output signal is fully
registered.
This means that the IRQ signal is no longer mask when the control enable
bit is not set. Instead modify the code to clear the interrupt when the
control enable bit is not set. This turns it into a true reset for the
internal state.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The I2S interface has a clock associated to it twice, this will generate a
critical warning when using the core, so remove one of them.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>