= WARP v3 Clock Controller (w3_clock_controller_axi) = This core implements an SPI master for reading/writing registers in the AD9512 clock buffers on the WARP v3 board. For details about how these buffers are connected to the FPGA and RF interfaces, refer to the [wiki:HardwareUsersGuides/WARPv3/Clocking WARP v3 User Guide Clocking] section. This core also manages the interfaces on the CM-MMCX and CM-PLL clock modules for WARP v3. The w3_clock_controller_axi core is packaged as a pcore which can instantiated in an XPS project. The design has been tested in hardware using Xilinx ISE 14.4. == Overview == Clock configuration in a WARP v3 FPGA design occurs in three stages: 1. '''Pre-boot:''' the minimum set of registers are written directly by the w3_clock_controller_axi HDL to achieve an 80MHz clock from the sampling clock buffer to the FPGA. All FPGA logic clocked by the sampling clock 1. '''Driver initialization:''' the w3_clock_controller_axi driver {{{clk_init()}}} function writes additional registers in the sampling and RF reference clock buffers, establishing a default configuration suitable for most applications 1. '''Software application:''' the user application running in the MicroBlaze calls other functions in the w3_clock_controller_axi driver to customize the clock configuration The sections below describe these three stages in detail. === Pre-Boot Configuration === In a typical FPGA design for WARP v3 most of the FPGA logic is clocked synchronous to the RF interface digital I/Q signals. This is true for both the [wiki:802.11 802.11 Reference Design] and [wiki:WARPLab WARPLab Reference Design], which use an 80MHz master clock sourced from the sampling clock buffer. In these designs the sampling clock signal is fed into clock management circuits in the FPGA (IBUFG, MMCM, etc) and is distributed across the chip. These circuits must be held in reset until a valid sampling clock is present at the FPGA input pins. Establishing a stable 80MHz clock from the sampling clock buffer requires: 1. Configuring the divider and logic level of the buffer's output to the FPGA 1. Selecting (and possibly configuring) the clock source for the sampling clock buffer These steps require writing registers in the AD9512 buffer via its SPI interface. However the primary SPI master in the w3_clock_controller_axi core is part of logic attached to the AXI interconnect, clocked by the (not yet running) master clock. Thus the w3_clock_controller_axi HDL integrates a secondary SPI controller to perform initial setup of the clock circuits. The w3_clock_controller_axi HDL also supports run-time selection of various clock configurations using the switches on the CM-PLL and CM-MMCX clock modules. The core implements 7 configurations by default: {{{#!th Clock Module }}} {{{#!th Switches }}} {{{#!th Config }}} {{{#!th Default Settings }}} |---------------------------- {{{#!td style="background: #ffe" None }}} {{{#!td style="background: #ffe" --- }}} {{{#!td style="background: #ffe" {{{CFG_NOCM}}} }}} {{{#!td style="background: #ffe" * Select WARP v3 80MHz TCXO as sampling clock source * Set output to FPGA as LVDS, bypass divider }}} |---------------------------- {{{#!td rowspan=3 style="background: #fff" CM-MMCX }}} {{{#!td style="background: #fff" [[Image(cmmmcx_sipsw_cfgsel_01.png,nolink)]] }}} {{{#!td style="background: #fff" {{{CFG_CMMMCX_A}}} }}} {{{#!td style="background: #fff" * Select WARP v3 80MHz TCXO as sampling clock source * Set output to FPGA as LVDS, bypass divider }}} |---------------------------- {{{#!td style="background: #fff" [[Image(cmmmcx_sipsw_cfgsel_10.png,nolink)]] }}} {{{#!td style="background: #fff" {{{CFG_CMMMCX_B}}} }}} {{{#!td style="background: #fff" * Select clock module (MMCX Jack "Samp In") as sampling clock source * Set output to FPGA as LVDS, bypass divider }}} |---------------------------- {{{#!td style="background: #fff" [[Image(cmmmcx_sipsw_cfgsel_00.png,nolink)]] }}} {{{#!td style="background: #fff" {{{CFG_CMMMCX_C}}} }}} {{{#!td style="background: #fff" * Select clock module (MMCX connector "Samp In") as sampling clock source * Set output to FPGA as LVDS, bypass divider }}} |---------------------------- {{{#!td rowspan=3 style="background: #ffe" CM-PLL }}} {{{#!td style="background: #ffe" [[Image(cmpll_dipsw_cfgsel_101.png,nolink)]] }}} {{{#!td style="background: #ffe" {{{CFG_CMPLL_A}}} }}} {{{#!td style="background: #ffe" * Configure RF reference clock buffer to output 10MHz to clock module * Set PLL reference clock frequency to 10MHz * Select clock module (CM-PLL 80MHz VCXO) as sampling clock source * Set output to FPGA as LVDS, bypass divider }}} |---------------------------- {{{#!td style="background: #ffe" [[Image(cmpll_dipsw_cfgsel_110.png,nolink)]] }}} {{{#!td style="background: #ffe" {{{CFG_CMPLL_B}}} }}} {{{#!td style="background: #ffe" * Set PLL reference clock frequency to 10MHz * Select clock module (CM-PLL 80MHz VCXO) as sampling clock source * Set output to FPGA as LVDS, bypass divider }}} |---------------------------- {{{#!td style="background: #ffe" [[Image(cmpll_dipsw_cfgsel_111.png,nolink)]] }}} {{{#!td style="background: #ffe" {{{CFG_CMPLL_C}}} }}} {{{#!td style="background: #ffe" * Set PLL reference clock frequency to 80MHz * Select clock module (CM-PLL 80MHz VCXO) as sampling clock source * Set output to FPGA as LVDS, bypass divider }}} The w3_clock_controller_axi core uses the Xilinx PicoBlaze microcontroller to execute the pre-boot clock configuration process. PicoBlaze is an 8-bit microcontroller implemented in the fabric of the FPGA. The PicoBlaze controller executes a program stored in a block RAM whose contents are initialized in the HDL. In effect this block RAM acts as a ROM for the PicoBlaze program. The program is written in assembly code and assembled using the PicoBlaze assembler provided free by Xilinx. For an overview of the PicoBlaze program, refer to [browser:/PlatformSupport/CustomPeripherals/pcores/w3_clock_controller_axi_v4_00_a/hdl/verilog/picoblaze_src/prog_clk_config_boot.psc prog_clk_config_boot.psc] pseudo-code. The actual assembly program is available in [source:/PlatformSupport/CustomPeripherals/pcores/w3_clock_controller_axi_v4_00_a/hdl/verilog/picoblaze_src/prog_clk_config_boot.psm prog_clk_config_boot.psm]. It is '''not''' necessary to modify the PicoBlaze program to customize the register values written by the pre-boot logic. The PicoBlaze program can read custom configurations from the WARP v3 EEPROM, requiring no changes to the HDL or pre-built reference design hardware projects. Refer to the Custom Configurations section below for more details. For more information about the PicoBlaze microcontroller: * [http://www.xilinx.com/products/intellectual-property/picoblaze.html#documentation Xilinx PicoBlaze documentation] * [http://www.xilinx.com/ipcenter/processor_central/picoblaze/member/ Xilinx PicoBlaze source and tools] - w3_clock_controller_axi HDL uses PicoBlaze version 6 (KCPSM6) Rev 9 == Custom Configurations == The default configurations described above are implemented in the program ROM of the PicoBlaze microcontroller in the w3_clock_controller_axi core. These defaults can be overridden by programing new register address/data values in the WARP v3 EEPROM. The PicoBlaze program checks the EEPROM for valid clock configuration values on boot. If valid configuration options are found in the EEPROM the program loads these instead of the internal defaults. The configuration values are stored in the WARP v3 EEPROM starting at byte address 15000. Configuration values are stored as 2-byte address/data pairs, with each pair corresponding to a 1-byte register write via SPI to a single device. There are separate configuration values for the 3 SPI slave devices (the RF reference clock buffer, the sampling clock buffer and the PLL on the CM-PLL clock module). Multiple configurations can be defined for each device to support run-time selection of the active configuration via the clock module switches. The mapping of clock module switch settings to selected EEPROM configuration is the same as the mapping described above. Configuration values in the EEPROM are stored as pairs of address/data bytes. Each address/data pair specifies a single register write via SPI. Each address byte must be a valid register address for the selected device. The corresponding data byte must be a valid value for the selected register. The w3_clock_controller_axi core does not implement any validation in the register addresses or values. Invalid configuration values in the EEPROM will result in invalid configurations in hardware. The EEPROM addresses for the various clock configuration values are listed in the table below. A sample application to write configuration values to the EEPROM is available in [browser:/PlatformSupport/CustomPeripherals/pcores/w3_clock_controller_axi_v4_00_a/util/clk_cfg_eeprom_writer.c clk_cfg_eeprom_writer.c]. This example application encodes the same default register settings as the internal configuration values used by the HDL for non-EEPROM configuration. ||= EEPROM Bytes =||= Byte Values =||= Description =|| || 15000:15001 || {{{[0xA5 0xCD]}}} || Magic delimiter value indicating valid clock config values in EEPROM || |||||| '''RF Reference Clock Buffer Configs''' (up to 8 register values) || || 15002:15017 || {{{[A0 D0 ... A7 D7]}}} || RF reference clock buffer config {{{NOCM}}} || || 15018:15033 || {{{[A0 D0 ... A7 D7]}}} || RF reference clock buffer config {{{CM_MMCX_A}}} || || 15034:15049 || {{{[A0 D0 ... A7 D7]}}} || RF reference clock buffer config {{{CM_MMCX_B}}} || || 15050:15065 || {{{[A0 D0 ... A7 D7]}}} || RF reference clock buffer config {{{CM_MMCX_C}}} || || 15066:15081 || {{{[A0 D0 ... A7 D7]}}} || RF reference clock buffer config {{{CM_PLL_A}}} || || 15082:15097 || {{{[A0 D0 ... A7 D7]}}} || RF reference clock buffer config {{{CM_PLL_B}}} || || 15098:15113 || {{{[A0 D0 ... A7 D7]}}} || RF reference clock buffer config {{{CM_PLL_C}}} || |||||| '''Sampling Clock Buffer Configs''' (up to 8 register values) || || 15130:15145 || {{{[A0 D0 ... A7 D7]}}} || Sampling clock buffer config {{{NOCM}}} || || 15146:15161 || {{{[A0 D0 ... A7 D7]}}} || Sampling clock buffer config {{{CM_MMCX_A}}} || || 15162:15177 || {{{[A0 D0 ... A7 D7]}}} || Sampling clock buffer config {{{CM_MMCX_B}}} || || 15178:15193 || {{{[A0 D0 ... A7 D7]}}} || Sampling clock buffer config {{{CM_MMCX_C}}} || || 15194:15209 || {{{[A0 D0 ... A7 D7]}}} || Sampling clock buffer config {{{CM_PLL_A}}} || || 15210:15225 || {{{[A0 D0 ... A7 D7]}}} || Sampling clock buffer config {{{CM_PLL_B}}} || || 15226:15241 || {{{[A0 D0 ... A7 D7]}}} || Sampling clock buffer config {{{CM_PLL_C}}} || |||||| '''PLL Configs''' (up to 40 register values) || || 15258:15337 || {{{[A0 D0 ... A39 D39]}}} || PLL config {{{NOCM}}} || || 15338:15417 || {{{[A0 D0 ... A39 D39]}}} || PLL config {{{CM_PLL_A}}} || || 15418:15497 || {{{[A0 D0 ... A39 D39]}}} || PLL config {{{CM_PLL_B}}} || || 15498:15577 || {{{[A0 D0 ... A39 D39]}}} || PLL config {{{CM_PLL_C}}} || ---- == Driver Initialization == The w3_clock_controller_axi core includes a C driver for use by applications running in a MicroBlaze processor. The MicroBlaze application must initialize the w3_clock_controller_axi driver by calling {{{clk_init()}}} early in the application {{{main()}}}. The {{{clk_init()}}} function applies the following settings: * RF reference clock buffer * Enables 40MHz reference clock to RF A and RF B transceivers (sets OUT3 as 40MHz CMOS, p/n outputs active) * Disables output to FMC (OUT4) * Disables unused outputs (OUT1, OUT2) * Sampling clock buffer * Enables 40MHz clock to ADC/DAC on RF A and RF B (enables OUT0/OUT2, sets divider to 2) * Disables outputs to clock module (OUT1) and FMC (OUT4) == Software Application == After calling {{{clk_init()}}} the software application should use the w3_clock_controller_axi driver to modify any application-specific clock settings. For example if an application uses the FMC-RF-2X245 module the RF reference and sampling clock outputs to the FMC slot must be enabled '''before''' the radio_controller attempts to initialize the RF transceivers for RF C and RF D. The software application can also read the switches on clock modules to customize clock behavior at run time. Refer to the WARPLab Reference Design {{{node_clk_initialize()}}} function (in [browser:/ResearchApps/PHY/WARPLAB/WARPLab7/C_Code_Reference/wl_node.c?rev=4321#L545 wl_node.c]) for a good example of applying application-specific clock configurations. Refer to the [//svn/WARP/PlatformSupport/CustomPeripherals/pcores/w3_clock_controller_axi_v4_00_a/doc/html/api/group__user__functions.html w3_clock_controller_axi driver API documentation] for more details. = Using the Core in XPS = The w3_clock_controller_axi is packaged as a standard pcore, ready for instantiation in an XPS project. The core's AXI interface can be connected to an AXI lite or AXI interconnect. The must be assigned a memory address which is accessible by a MicroBlaze processor on the same interconnect. Some w3_clock_controller_axi ports must be connected to top-level FPGA pins. Other ports must be connected to other cores in the XPS project. A typical system is illustrated in the block diagram below. Refer to the WARPLab Reference Design or 802.11 Reference Design for good examples of XPS projects integrating the w3_clock_controller_axi core. [[Image(w3_clock_controller_block_diagram.png, width=500)]] The w3_clock_controller_axi core ports are described in the table below. ||= Port =||= Description =|| || S_AXI_ACLK || Clock for core logic and AXI interface; should be synchronous with RF interface sampling clocks || || S_AXI_* || AXI slave interface ports; connect to AXI interconnect || || at_boot_clk_in || Clock for pre-boot configuration logic. Connect to a the WARP v3 200MHz oscillator. || || at_boot_clk_in_valid || Qualifier for at_boot_clk_in input. Set to 1 when at_boot_clk_in is stable. || || at_boot_config_sw![2:0] || 3-bit switch from clock module. Connect directly to IOBs. These pins must have {{{PULLUP}}} constraints. || || at_boot_clkbuf_clocks_invalid || Output indicating status of pre-boot configuration. Logic 0 indicates pre-boot configuration is complete. Connect to MMCMs whose inputs use sampling or PLL clocks. || || samp_spi_* || SPI interface for sampling clock buffer. Connect directly to corresponding FPGA IOBs || || samp_func || Reset signal for sampling clock buffer. Connect directly to corresponding FPGA IOB || || rfref_spi_* || SPI interface for RF reference clock buffer. Connect directly to corresponding FPGA IOBs || || rfref_func || Reset signal for RF reference clock buffer. Connect directly to corresponding FPGA IOB || || cm_spi_* || SPI interface for CM-PLL clock module PLL/buffer. Connect directly to corresponding FPGA IOBs || || cm_pll_status || Status signal from the CM-PLL clock module PLL/buffer. Connect directly to corresponding FPGA IOB || || pll_ref_clk || Reference clock for the CM-PLL clock module PLL. Connect to the clock signal driven by the CM-PLL on pins 35/36 of the clock module header || || uart_tx || Output from PicoBlaze UART. Connect directly to USB UART Tx or w3_boot_io_mux instance || || iic_eeprom_scl_* || Tri-state buffer I/O/T for IIC clock signal. Connect directly to EEPROM SCL IOBUF instance or via w3_boot_io_mux instance || || iic_eeprom_sda_* || Tri-state buffer I/O/T for IIC data signal. Connect directly to EEPROM SDA IOBUF instance or via w3_boot_io_mux instance || == Source == The full hardware and software source code is available in the repository: [source:/PlatformSupport/CustomPeripherals/pcores/w3_clock_controller_axi_v4_00_a]. The VHDL, Verilog and C source code are made available under the [wiki:/license WARP license].