Skip to content

Commit

Permalink
docs/library: Add axi_clock_monitor IP doc & Update IP GUI
Browse files Browse the repository at this point in the history
Signed-off-by: Iulia Moldovan <[email protected]>
  • Loading branch information
IuliaCMoldovan committed Sep 30, 2024
1 parent 6fbb720 commit 85c776e
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 20 deletions.
132 changes: 132 additions & 0 deletions docs/library/axi_clock_monitor/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
.. _axi_clock_monitor:

AXI Clock Monitor
===============================================================================

.. hdl-component-diagram::

The :git-hdl:`AXI Clock Monitor <library/axi_clock_monitor>` IP is used to
measure clocks in the system. It allows up to 16 clocks to be measured at a
time.

Features
--------------------------------------------------------------------------------

* Can measure up to 16 clocks (set to 1 by default)
* AXI-based configuration
* Vivado and Quartus compatible

Files
--------------------------------------------------------------------------------

.. list-table::
:header-rows: 1

* - Name
- Description
* - :git-hdl:`library/axi_clock_monitor/axi_clock_monitor.v`
- Verilog source for the instance
* - :git-hdl:`library/axi_clock_monitor/axi_clock_monitor_ip.tcl`
- Tcl source describing the instance for Vivado
* - :git-hdl:`library/axi_clock_monitor/axi_clock_monitor_hw.tcl`
- Tcl source describing the instance for Quartus

Configuration Parameters
--------------------------------------------------------------------------------

.. hdl-parameters::
:path: library/axi_clock_monitor

.. _axi_clock_monitor interface:

Interface
--------------------------------------------------------------------------------

.. hdl-interfaces::
:path: library/axi_clock_monitor

Detailed Description
--------------------------------------------------------------------------------

The top module instantiates:

* the :git-hdl:`clock monitor module <library/common/up_clock_mon.v>`
* the :git-hdl:`AXI handling interface <library/common/up_axi.v>`

How to instantiate it in your project:

#. build this IP by going to the :git-hdl:`library/axi_clock_monitor` folder
and running `make`. For more details on building this, check out our
:ref:`guide <build_hdl>`. Another requirement is to have your desired
project already built.
#. import the IP core to your block design, by opening the Block Design of
the already built project, right-clicking in the Diagram then "Add IP"
(or CTRL + I) and typing "axi_clock_monitor"
#. configure your IP by specifying how many clocks you want to monitor
#. connect the IP to the AXI interface
#. assign a base address to the IP core, such that it doesn't overlap with other
components
#. assign clock signals to the clock inputs
#. build again the HDL (now containing this module as well) by clicking
"Generate Bitstream" from "Program and Debug" section in Vivado

Register Map
--------------------------------------------------------------------------------

.. hdl-regmap::
:name: axi_clock_monitor
:no-type-info:

Software Guidelines
--------------------------------------------------------------------------------

.. note::

Only no-OS software is supported.

We use software to access the core's registers to get the data from the IP.

The following example contains a simple function that reads all the info
from the IP and prints it on the serial terminal:

.. code-block:: C
:linenos:
void clock_monitor_info (uint32_t core_base_addr, uint32_t axi_clock_speed_mhz) {
uint32_t clock_ratio = 0;
uint32_t clk1_addr = 0x40;
uint32_t n_clocks = 0;
uint32_t info_var = 0;
uint8_t n = 0;
info_var = axi_io_read(core_base_addr);
printf("PCORE_VERSION = %d\n", info_var);
info_var = axi_io_read(core_base_addr, 4);
printf("ID = %d\n", info_var);
n_clocks = axi_io_read((core_base_addr, 12));
printf("n clocks = %d\n", n_clocks);
info_var = axi_io_read(core_base_addr, 16);
printf("RESET OUT = %d\n", info_var);
while (n < n_clocks & n < 16) {
clock_ratio = axi_io_read((core_base_addr, clk1_addr + 4*n));
if (clock_ratio == 0) {
printf("Measured clock_%d: off\n", n);
} else {
printf("Measured clock_%d: %d MHz\n", n,
(clock_ratio * axi_clock_speed_mhz + 0x7fff) >> 16);
}
n++;
}
}
To call the function, consider the following parameters:

* `core_base_addr` will take the value of the base address set at step 5 of
the HDL instantiation
* `axi_clock_speed_mhz` will be the reference frequency. In most cases, we
assume this parameter to be 100 [MHz]
1 change: 1 addition & 0 deletions docs/library/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Utilities
axi_adc_trigger/index
axi_adxcvr/index
axi_clkgen/index
axi_clock_monitor/index
axi_dac_interpolate/index
axi_fan_control/index
axi_laser_driver/index
Expand Down
47 changes: 27 additions & 20 deletions library/axi_clock_monitor/axi_clock_monitor_ip.tcl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###############################################################################
## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved.
## Copyright (C) 2022-2024 Analog Devices, Inc. All rights reserved.
### SPDX short identifier: ADIBSD
###############################################################################

Expand All @@ -16,41 +16,48 @@ adi_ip_files axi_clock_monitor [list \

adi_ip_properties axi_clock_monitor

set_property company_url {https://wiki.analog.com/resources/fpga/docs/axi_clock_monitor} [ipx::current_core]
set cc [ipx::current_core]
set_property display_name {AXI Clock Monitor} $cc
set_property company_url {https://analogdevicesinc.github.io/hdl/library/axi_clock_monitor/index.html} $cc

set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 1} \
[ipx::get_ports *_1* -of_objects [ipx::current_core]]
[ipx::get_ports *_1* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 2} \
[ipx::get_ports *_2* -of_objects [ipx::current_core]]
[ipx::get_ports *_2* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 3} \
[ipx::get_ports *_3* -of_objects [ipx::current_core]]
[ipx::get_ports *_3* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 4} \
[ipx::get_ports *_4* -of_objects [ipx::current_core]]
[ipx::get_ports *_4* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 5} \
[ipx::get_ports *_5* -of_objects [ipx::current_core]]
[ipx::get_ports *_5* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 6} \
[ipx::get_ports *_6* -of_objects [ipx::current_core]]
[ipx::get_ports *_6* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 7} \
[ipx::get_ports *_7* -of_objects [ipx::current_core]]
[ipx::get_ports *_7* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 8 } \
[ipx::get_ports *_8* -of_objects [ipx::current_core]]
[ipx::get_ports *_8* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 9 } \
[ipx::get_ports *_9* -of_objects [ipx::current_core]]
[ipx::get_ports *_9* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 10} \
[ipx::get_ports *_10* -of_objects [ipx::current_core]]
[ipx::get_ports *_10* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 11} \
[ipx::get_ports *_11* -of_objects [ipx::current_core]]
[ipx::get_ports *_11* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 12} \
[ipx::get_ports *_12* -of_objects [ipx::current_core]]
[ipx::get_ports *_12* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 13} \
[ipx::get_ports *_13* -of_objects [ipx::current_core]]
[ipx::get_ports *_13* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 14} \
[ipx::get_ports *_14* -of_objects [ipx::current_core]]
[ipx::get_ports *_14* -of_objects $cc]
set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.NUM_OF_CLOCKS')) > 15} \
[ipx::get_ports *_15* -of_objects [ipx::current_core]]
[ipx::get_ports *_15* -of_objects $cc]

ipx::infer_bus_interface reset xilinx.com:signal:reset_rtl:1.0 [ipx::current_core]

ipx::save_core [ipx::current_core]
set_property widget {textEdit} [ipgui::get_guiparamspec -name "NUM_OF_CLOCKS" -component [ipx::current_core] ]
set_property -dict [list \
"value_validation_type" "range_long" \
"value_validation_range_minimum" "1" \
"value_validation_range_maximum" "16"
] [ipx::get_user_parameters NUM_OF_CLOCKS -of_objects $cc]

ipx::infer_bus_interface reset xilinx.com:signal:reset_rtl:1.0 $cc

ipx::save_core $cc

0 comments on commit 85c776e

Please sign in to comment.