Adds a BUILD_SEED make variable that can be set to a 32-bit integer, and adds an FPGA read-only register initialized by this variable. Changing this variable will randomly affect the FPGA build results. This can be useful when your build fails timing by a small amount, allowing you to build again and get different results with the same code. For example, you could run the following to produce an FPGA build with different timing results from the default build: make X310_XG BUILD_SEED=123 Original-commit: 3a3a03486f9221c2e59fa6d0826c23d17730956d
718 lines
27 KiB
Verilog
718 lines
27 KiB
Verilog
//
|
|
// Copyright 2021 Ettus Research, A National Instruments Brand
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0
|
|
//
|
|
// Module: x4xx_global_regs
|
|
//
|
|
// Description:
|
|
//
|
|
// This module contains the motherboard registers for the USRP.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// REG_BASE : Base address to use for the registers
|
|
// CHDR_CLK_RATE : Rate of rfnoc_chdr_clk in Hz
|
|
// CHDR_W : CHDR protocol width
|
|
// RFNOC_PROTOVER : RFNoC protocol version (major in most-significant byte,
|
|
// Minor is least significant byte).
|
|
// NUM_TIMEKEEPERS : Number of timekeeper modules
|
|
// PCIE_PRESENT : Indicates if PCIe is present in this image
|
|
//
|
|
|
|
`default_nettype none
|
|
|
|
|
|
module x4xx_global_regs #(
|
|
parameter REG_BASE = 0,
|
|
parameter REG_SIZE = 'hC00,
|
|
parameter CHDR_CLK_RATE = 200000000,
|
|
parameter CHDR_W = 64,
|
|
parameter RFNOC_PROTOVER = {8'd1, 8'd0},
|
|
parameter NUM_TIMEKEEPERS = 32'd1,
|
|
parameter PCIE_PRESENT = 0
|
|
) (
|
|
// Slave ctrlport interface
|
|
input wire s_ctrlport_clk,
|
|
input wire s_ctrlport_rst,
|
|
input wire s_ctrlport_req_wr,
|
|
input wire s_ctrlport_req_rd,
|
|
input wire [19:0] s_ctrlport_req_addr,
|
|
input wire [31:0] s_ctrlport_req_data,
|
|
output reg s_ctrlport_resp_ack = 1'b0,
|
|
output reg [ 1:0] s_ctrlport_resp_status = 2'b00,
|
|
output reg [31:0] s_ctrlport_resp_data = {32 {1'bX}},
|
|
|
|
// RFNoC CHDR clock/reset
|
|
input wire rfnoc_chdr_clk,
|
|
input wire rfnoc_chdr_rst,
|
|
|
|
// PPS and clock control signals (domain: s_ctrlport_clk)
|
|
output wire [ 1:0] pps_select,
|
|
output wire [ 1:0] trig_io_select,
|
|
output reg pll_sync_trigger = 1'b0,
|
|
output reg [ 7:0] pll_sync_delay = 8'b0,
|
|
input wire pll_sync_done,
|
|
output reg [ 7:0] pps_brc_delay = 8'b0,
|
|
output reg [25:0] pps_prc_delay = 26'b0,
|
|
output reg [ 1:0] prc_rc_divider = 2'b0,
|
|
output reg pps_rc_enabled = 1'b0,
|
|
|
|
// Misc control and status signals (domain: s_ctrlport_clk)
|
|
input wire [31:0] qsfp_port_0_0_info,
|
|
input wire [31:0] qsfp_port_0_1_info,
|
|
input wire [31:0] qsfp_port_0_2_info,
|
|
input wire [31:0] qsfp_port_0_3_info,
|
|
input wire [31:0] qsfp_port_1_0_info,
|
|
input wire [31:0] qsfp_port_1_1_info,
|
|
input wire [31:0] qsfp_port_1_2_info,
|
|
input wire [31:0] qsfp_port_1_3_info,
|
|
output reg mfg_test_en_fabric_clk = 1'b0,
|
|
output reg mfg_test_en_gty_rcv_clk = 1'b0,
|
|
input wire fpga_aux_ref,
|
|
|
|
// Device ID used by RFNoC, transports, etc. (Domain: rfnoc_chdr_clk)
|
|
output reg [15:0] device_id
|
|
);
|
|
|
|
`include "../../lib/rfnoc/core/ctrlport.vh"
|
|
`include "regmap/global_regs_regmap_utils.vh"
|
|
`include "regmap/versioning_regs_regmap_utils.vh"
|
|
|
|
// Make DEVICE_ID default to anything but 0, since that has special meaning
|
|
localparam [DEVICE_ID_SIZE-1:0] DEFAULT_DEVICE_ID = 1;
|
|
|
|
// Internal registers (Domain: s_ctrlport_clk)
|
|
reg [ DEVICE_ID_SIZE-1:0] device_id_reg = DEFAULT_DEVICE_ID;
|
|
reg [SCRATCH_REG_SIZE-1:0] scratch_reg = {SCRATCH_REG_SIZE{1'b0}};
|
|
reg [SERIAL_NUM_HIGH_REG_SIZE + SERIAL_NUM_LOW_REG_SIZE-1:0] serial_num_reg = 0;
|
|
|
|
// CHDR clock counter (Domain: rfnoc_chdr_clk)
|
|
reg [CHDR_CLK_COUNT_REG_SIZE-1:0] chdr_counter = {CHDR_CLK_COUNT_REG_SIZE{1'b0}};
|
|
|
|
// CHDR clock counter register (Domain: s_ctrlport_clk)
|
|
wire chdr_counter_fifo_valid;
|
|
wire [CHDR_CLK_COUNT_REG_SIZE-1:0] chdr_counter_fifo_data;
|
|
reg [CHDR_CLK_COUNT_REG_SIZE-1:0] chdr_counter_reg = 0;
|
|
|
|
// Measure PPS for manufacturing test
|
|
reg [MFG_TEST_FPGA_AUX_REF_FREQ_SIZE-1:0] fpga_aux_ref_freq = 0;
|
|
|
|
reg [PPS_SELECT_SIZE-1:0] pps_select_reg = PPS_INT_25MHZ;
|
|
assign pps_select = pps_select_reg;
|
|
|
|
reg [TRIGGER_IO_SELECT_SIZE-1:0] trig_io_select_reg = TRIG_IO_INPUT;
|
|
assign trig_io_select = trig_io_select_reg;
|
|
|
|
// Bus counter in the rfnoc_chdr_clk domain.
|
|
always @(posedge rfnoc_chdr_clk) begin
|
|
if (rfnoc_chdr_rst) begin
|
|
chdr_counter <= {CHDR_CLK_COUNT_REG_SIZE{1'b0}};
|
|
end else begin
|
|
chdr_counter <= chdr_counter + 1;
|
|
end
|
|
end
|
|
|
|
// Safely cross clock domains for the CHDR counter.
|
|
handshake #(
|
|
.WIDTH (CHDR_CLK_COUNT_REG_SIZE)
|
|
) handshake_chdr_counter (
|
|
.clk_a (rfnoc_chdr_clk),
|
|
.rst_a (rfnoc_chdr_rst),
|
|
.valid_a (1'b1),
|
|
.data_a (chdr_counter),
|
|
.busy_a (),
|
|
.clk_b (s_ctrlport_clk),
|
|
.valid_b (chdr_counter_fifo_valid),
|
|
.data_b (chdr_counter_fifo_data)
|
|
);
|
|
|
|
// Register a valid FIFO output to ensure the counter is always valid.
|
|
always @(posedge s_ctrlport_clk) begin
|
|
if (s_ctrlport_rst) begin
|
|
chdr_counter_reg <= 0;
|
|
end else begin
|
|
if (chdr_counter_fifo_valid) begin
|
|
chdr_counter_reg <= chdr_counter_fifo_data;
|
|
end
|
|
end
|
|
end
|
|
|
|
wire [31:0] build_datestamp;
|
|
|
|
USR_ACCESSE2 usr_access_i (
|
|
.DATA(build_datestamp), .CFGCLK(), .DATAVALID()
|
|
);
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Global Registers
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Check that address is within this module's range.
|
|
wire address_in_range = (s_ctrlport_req_addr >= REG_BASE) && (s_ctrlport_req_addr < REG_BASE + REG_SIZE);
|
|
|
|
// Registers implementation
|
|
always @ (posedge s_ctrlport_clk) begin
|
|
if (s_ctrlport_rst) begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
s_ctrlport_resp_data <= {32 {1'bX}};
|
|
s_ctrlport_resp_status <= 2'b00;
|
|
scratch_reg <= {SCRATCH_REG_SIZE{1'b0}};
|
|
serial_num_reg <= 0;
|
|
pps_select_reg <= PPS_INT_25MHZ;
|
|
trig_io_select_reg <= TRIG_IO_INPUT;
|
|
device_id_reg <= DEFAULT_DEVICE_ID;
|
|
|
|
end else begin
|
|
// Write registers
|
|
if (s_ctrlport_req_wr) begin
|
|
// Acknowledge by default
|
|
s_ctrlport_resp_ack <= 1'b1;
|
|
s_ctrlport_resp_data <= 32'h0;
|
|
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
|
|
|
case (s_ctrlport_req_addr)
|
|
REG_BASE + SCRATCH_REG: begin
|
|
scratch_reg <= s_ctrlport_req_data;
|
|
end
|
|
|
|
REG_BASE + DEVICE_ID_REG: begin
|
|
device_id_reg <= s_ctrlport_req_data[DEVICE_ID_MSB:DEVICE_ID];
|
|
end
|
|
|
|
REG_BASE + CLOCK_CTRL_REG: begin
|
|
pps_select_reg <= s_ctrlport_req_data[PPS_SELECT_MSB:PPS_SELECT];
|
|
trig_io_select_reg <= s_ctrlport_req_data[TRIGGER_IO_SELECT_MSB:TRIGGER_IO_SELECT];
|
|
pll_sync_delay <= s_ctrlport_req_data[PLL_SYNC_DELAY_MSB:PLL_SYNC_DELAY];
|
|
pll_sync_trigger <= s_ctrlport_req_data[PLL_SYNC_TRIGGER];
|
|
pps_brc_delay <= s_ctrlport_req_data[PPS_BRC_DELAY_MSB:PPS_BRC_DELAY];
|
|
end
|
|
|
|
REG_BASE + PPS_CTRL_REG: begin
|
|
pps_prc_delay <= s_ctrlport_req_data[PPS_PRC_DELAY_MSB:PPS_PRC_DELAY];
|
|
prc_rc_divider <= s_ctrlport_req_data[PRC_RC_DIVIDER_MSB:PRC_RC_DIVIDER];
|
|
pps_rc_enabled <= s_ctrlport_req_data[PPS_RC_ENABLED];
|
|
end
|
|
|
|
REG_BASE + SERIAL_NUM_LOW_REG: begin
|
|
serial_num_reg[SERIAL_NUM_LOW_REG_SIZE-1:0] <= s_ctrlport_req_data;
|
|
end
|
|
|
|
REG_BASE + SERIAL_NUM_HIGH_REG: begin
|
|
serial_num_reg[SERIAL_NUM_LOW_REG_SIZE +: SERIAL_NUM_HIGH_REG_SIZE] <= s_ctrlport_req_data;
|
|
end
|
|
|
|
REG_BASE + MFG_TEST_CTRL_REG: begin
|
|
mfg_test_en_fabric_clk <= s_ctrlport_req_data[MFG_TEST_EN_FABRIC_CLK];
|
|
mfg_test_en_gty_rcv_clk <= s_ctrlport_req_data[MFG_TEST_EN_GTY_RCV_CLK];
|
|
end
|
|
|
|
// No register implementation for provided address
|
|
default: begin
|
|
// Acknowledge and provide error status if address is in range
|
|
if (address_in_range) begin
|
|
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
|
|
|
|
// No response if out of range
|
|
end else begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
end
|
|
end
|
|
endcase
|
|
|
|
// Read registers
|
|
end else if (s_ctrlport_req_rd) begin
|
|
// Acknowledge by default
|
|
s_ctrlport_resp_ack <= 1'b1;
|
|
s_ctrlport_resp_data <= 32'h0;
|
|
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
|
|
|
case (s_ctrlport_req_addr)
|
|
REG_BASE + COMPAT_NUM_REG: begin
|
|
s_ctrlport_resp_data[COMPAT_MAJOR_MSB:COMPAT_MAJOR] <= FPGA_CURRENT_VERSION_MAJOR;
|
|
s_ctrlport_resp_data[COMPAT_MINOR_MSB:COMPAT_MINOR] <= FPGA_CURRENT_VERSION_MINOR;
|
|
end
|
|
|
|
REG_BASE + DATESTAMP_REG: begin
|
|
s_ctrlport_resp_data <= build_datestamp;
|
|
end
|
|
|
|
REG_BASE + GIT_HASH_REG: begin
|
|
`ifndef GIT_HASH
|
|
`define GIT_HASH 32'h0BADC0DE
|
|
`endif
|
|
s_ctrlport_resp_data <= `GIT_HASH;
|
|
end
|
|
|
|
REG_BASE + SCRATCH_REG: begin
|
|
s_ctrlport_resp_data <= scratch_reg;
|
|
end
|
|
|
|
REG_BASE + DEVICE_ID_REG: begin
|
|
if (PCIE_PRESENT) begin
|
|
s_ctrlport_resp_data[PCIE_PRESENT_BIT] <= 1'b1;
|
|
end
|
|
s_ctrlport_resp_data[DEVICE_ID_MSB:DEVICE_ID] <= device_id_reg;
|
|
end
|
|
|
|
REG_BASE + RFNOC_INFO_REG: begin
|
|
s_ctrlport_resp_data[CHDR_WIDTH_MSB:CHDR_WIDTH] <= CHDR_W[CHDR_WIDTH_SIZE-1:0];
|
|
s_ctrlport_resp_data[RFNOC_PROTO_MAJOR_MSB:RFNOC_PROTO_MAJOR] <= RFNOC_PROTOVER[RFNOC_PROTO_MAJOR_MSB:RFNOC_PROTO_MAJOR];
|
|
s_ctrlport_resp_data[RFNOC_PROTO_MINOR_MSB:RFNOC_PROTO_MINOR] <= RFNOC_PROTOVER[RFNOC_PROTO_MINOR_MSB:RFNOC_PROTO_MINOR];
|
|
end
|
|
|
|
REG_BASE + CLOCK_CTRL_REG: begin
|
|
s_ctrlport_resp_data[PPS_SELECT_MSB:PPS_SELECT] <= pps_select_reg;
|
|
s_ctrlport_resp_data[PLL_SYNC_DELAY_MSB:PLL_SYNC_DELAY] <= pll_sync_delay;
|
|
s_ctrlport_resp_data[PLL_SYNC_DONE] <= pll_sync_done;
|
|
s_ctrlport_resp_data[TRIGGER_IO_SELECT_MSB:TRIGGER_IO_SELECT] <= trig_io_select_reg;
|
|
s_ctrlport_resp_data[PPS_BRC_DELAY_MSB:PPS_BRC_DELAY] <= pps_brc_delay;
|
|
end
|
|
|
|
REG_BASE + PPS_CTRL_REG: begin
|
|
s_ctrlport_resp_data[PPS_RC_ENABLED] <= pps_rc_enabled;
|
|
s_ctrlport_resp_data[PRC_RC_DIVIDER_MSB:PRC_RC_DIVIDER] <= prc_rc_divider;
|
|
s_ctrlport_resp_data[PPS_PRC_DELAY_MSB:PPS_PRC_DELAY] <= pps_prc_delay;
|
|
end
|
|
|
|
REG_BASE + CHDR_CLK_RATE_REG: begin
|
|
s_ctrlport_resp_data <= CHDR_CLK_RATE[CHDR_CLK_RATE_REG_SIZE-1:0];
|
|
end
|
|
|
|
REG_BASE + BUILD_SEED_REG: begin
|
|
`ifndef BUILD_SEED
|
|
`define BUILD_SEED 32'b0
|
|
`endif
|
|
s_ctrlport_resp_data <= `BUILD_SEED;
|
|
end
|
|
|
|
REG_BASE + CHDR_CLK_COUNT_REG: begin
|
|
s_ctrlport_resp_data <= chdr_counter_reg;
|
|
end
|
|
|
|
REG_BASE + QSFP_PORT_0_0_INFO_REG: begin
|
|
s_ctrlport_resp_data <= qsfp_port_0_0_info;
|
|
end
|
|
|
|
REG_BASE + QSFP_PORT_0_1_INFO_REG: begin
|
|
s_ctrlport_resp_data <= qsfp_port_0_1_info;
|
|
end
|
|
|
|
REG_BASE + QSFP_PORT_0_2_INFO_REG: begin
|
|
s_ctrlport_resp_data <= qsfp_port_0_2_info;
|
|
end
|
|
|
|
REG_BASE + QSFP_PORT_0_3_INFO_REG: begin
|
|
s_ctrlport_resp_data <= qsfp_port_0_3_info;
|
|
end
|
|
|
|
REG_BASE + QSFP_PORT_1_0_INFO_REG: begin
|
|
s_ctrlport_resp_data <= qsfp_port_1_0_info;
|
|
end
|
|
|
|
REG_BASE + QSFP_PORT_1_1_INFO_REG: begin
|
|
s_ctrlport_resp_data <= qsfp_port_1_1_info;
|
|
end
|
|
|
|
REG_BASE + QSFP_PORT_1_2_INFO_REG: begin
|
|
s_ctrlport_resp_data <= qsfp_port_1_2_info;
|
|
end
|
|
|
|
REG_BASE + QSFP_PORT_1_3_INFO_REG: begin
|
|
s_ctrlport_resp_data <= qsfp_port_1_3_info;
|
|
end
|
|
|
|
REG_BASE + NUM_TIMEKEEPERS_REG: begin
|
|
s_ctrlport_resp_data <= NUM_TIMEKEEPERS[NUM_TIMEKEEPERS_REG_SIZE-1:0];
|
|
end
|
|
|
|
REG_BASE + SERIAL_NUM_LOW_REG: begin
|
|
s_ctrlport_resp_data <= serial_num_reg[SERIAL_NUM_LOW_REG_SIZE-1:0];
|
|
end
|
|
|
|
REG_BASE + SERIAL_NUM_HIGH_REG: begin
|
|
s_ctrlport_resp_data <= serial_num_reg[SERIAL_NUM_LOW_REG_SIZE +: SERIAL_NUM_HIGH_REG_SIZE];
|
|
end
|
|
|
|
REG_BASE + MFG_TEST_CTRL_REG: begin
|
|
s_ctrlport_resp_data[MFG_TEST_EN_FABRIC_CLK] <= mfg_test_en_fabric_clk;
|
|
s_ctrlport_resp_data[MFG_TEST_EN_GTY_RCV_CLK] <= mfg_test_en_gty_rcv_clk;
|
|
end
|
|
|
|
REG_BASE + MFG_TEST_STATUS_REG: begin
|
|
s_ctrlport_resp_data[MFG_TEST_FPGA_AUX_REF_FREQ_MSB:MFG_TEST_FPGA_AUX_REF_FREQ] <= fpga_aux_ref_freq;
|
|
end
|
|
|
|
// No register implementation for provided address
|
|
default: begin
|
|
// Acknowledge and provide error status if address is in range
|
|
if (address_in_range) begin
|
|
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
|
|
|
|
// No response if out of range
|
|
end else begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
end
|
|
end
|
|
endcase
|
|
|
|
end else begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
// Assign Device ID register (Domain: s_ctrlport_clk) to module
|
|
// output (Domain: rfnoc_chdr_clk).
|
|
|
|
wire device_id_fifo_valid;
|
|
wire [DEVICE_ID_SIZE-1:0] device_id_fifo_data;
|
|
|
|
// Clock-crossing for device_id.
|
|
handshake #(
|
|
.WIDTH (DEVICE_ID_SIZE)
|
|
) handshake_device_id (
|
|
.clk_a (s_ctrlport_clk),
|
|
.rst_a (s_ctrlport_rst),
|
|
.valid_a (1'b1),
|
|
.data_a (device_id_reg),
|
|
.busy_a (),
|
|
.clk_b (rfnoc_chdr_clk),
|
|
.valid_b (device_id_fifo_valid),
|
|
.data_b (device_id_fifo_data)
|
|
);
|
|
|
|
// Register the handshake output to ensure device_id is always valid.
|
|
always @(posedge rfnoc_chdr_clk) begin
|
|
if (rfnoc_chdr_rst) begin
|
|
device_id <= 'bX;
|
|
end else begin
|
|
if (device_id_fifo_valid) begin
|
|
device_id <= device_id_fifo_data;
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// FPGA_REF_CLK Test
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Count the number of clocks on the incoming PPS for manufacturing test
|
|
// validation.
|
|
reg [25:0] fpga_aux_ref_cnt = 0;
|
|
wire fpga_aux_ref_sc1;
|
|
reg fpga_aux_ref_sc2 = 1'b0;
|
|
|
|
synchronizer #(
|
|
.STAGES (2),
|
|
.WIDTH (1),
|
|
.INITIAL_VAL (1'h0)
|
|
) synchronizer_fpga_aux_ref (
|
|
.clk (s_ctrlport_clk),
|
|
.rst (1'b0),
|
|
.in (fpga_aux_ref),
|
|
.out (fpga_aux_ref_sc1)
|
|
);
|
|
|
|
// 1.2 seconds with a 40 Mhz clock
|
|
localparam FPGA_AUX_REF_CNT_MAX = 48*1000*1000;
|
|
|
|
// Registers implementation
|
|
always @ (posedge s_ctrlport_clk) begin
|
|
if (s_ctrlport_rst) begin
|
|
fpga_aux_ref_sc2 <= 1'b0;
|
|
fpga_aux_ref_freq <= 0;
|
|
fpga_aux_ref_cnt <= 0;
|
|
end else begin
|
|
fpga_aux_ref_sc2 <= fpga_aux_ref_sc1;
|
|
// Detect rising edge (Was low, now is high)
|
|
if (!fpga_aux_ref_sc2 && fpga_aux_ref_sc1) begin
|
|
// if the count is less than max
|
|
if (fpga_aux_ref_cnt < FPGA_AUX_REF_CNT_MAX) begin
|
|
fpga_aux_ref_freq <= fpga_aux_ref_cnt;
|
|
// if count reached max
|
|
end else begin
|
|
fpga_aux_ref_freq <= 0;
|
|
end
|
|
// reset the counter at each rising edge
|
|
fpga_aux_ref_cnt <= 0;
|
|
end else begin
|
|
//stop incrementing at the max value
|
|
if (fpga_aux_ref_cnt < FPGA_AUX_REF_CNT_MAX) begin
|
|
fpga_aux_ref_cnt <= fpga_aux_ref_cnt+1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
|
|
`default_nettype wire
|
|
|
|
|
|
//XmlParse xml_on
|
|
//<regmap name="GLOBAL_REGS_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
|
|
// <group name="GLOBAL_REGS">
|
|
//
|
|
// <register name="COMPAT_NUM_REG" offset="0x00" size="32" writable="false">
|
|
// <info>Revision number</info>
|
|
// <bitfield name="COMPAT_MINOR" range="15..0"/>
|
|
// <bitfield name="COMPAT_MAJOR" range="31..16"/>
|
|
// </register>
|
|
// <register name="DATESTAMP_REG" offset="0x04" size="32" writable="false">
|
|
// <info>Build datestamp (32-bit)</info>
|
|
// <bitfield name="SECONDS" range="5..0"/>
|
|
// <bitfield name="MINUTES" range="11..6"/>
|
|
// <bitfield name="HOUR" range="16..12"/>
|
|
// <bitfield name="YEAR" range="22..17">
|
|
// <info>This is the year number after 2000 (e.g. 2019 = d19).</info>
|
|
// </bitfield>
|
|
// <bitfield name="MONTH" range="26..23"/>
|
|
// <bitfield name="DAY" range="31..27"/>
|
|
// </register>
|
|
// <register name="GIT_HASH_REG" offset="0x08" size="32" writable="false">
|
|
// <info>Git hash of source commit.</info>
|
|
// </register>
|
|
// <register name="SCRATCH_REG" offset="0x0C" size="32">
|
|
// <info>Scratch register for testing.</info>
|
|
// </register>
|
|
// <register name="DEVICE_ID_REG" offset="0x10" size="32">
|
|
// <info>Register that contains the motherboard's device ID.</info>
|
|
// <bitfield name="PCIE_PRESENT_BIT" range="31">
|
|
// <info>Set to 1 if PCI-Express core is present in FPGA design.</info>
|
|
// </bitfield>
|
|
// <bitfield name="DEVICE_ID" range="15..0"/>
|
|
// </register>
|
|
// <register name="RFNOC_INFO_REG" offset="0x14" size="32" writable="false">
|
|
// <info>Register that provides information on the RFNoC protocol.</info>
|
|
// <bitfield name="RFNOC_PROTO_MINOR" range="7..0"/>
|
|
// <bitfield name="RFNOC_PROTO_MAJOR" range="15..8"/>
|
|
// <bitfield name="CHDR_WIDTH" range="31..16"/>
|
|
// </register>
|
|
// <register name="CLOCK_CTRL_REG" offset="0x18" size="32">
|
|
// <info>Control register for clocking resources.</info>
|
|
// <bitfield name="PPS_SELECT" range="1..0" initialvalue="PPS_INT_25MHZ">
|
|
// <enumeratedtype name="PPS_ENUM">
|
|
// <value name="PPS_INT_25MHZ" integer="0"/>
|
|
// <value name="PPS_INT_10MHZ" integer="1"/>
|
|
// <value name="PPS_EXT" integer="2"/>
|
|
// </enumeratedtype>
|
|
// <info>
|
|
// Select the source of the PPS signal.
|
|
// For the internal generation the value depending on the base reference clock has to be chosen.
|
|
// The external reference is taken from the PPS_IN pin and is independent of the base reference clock.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="REF_SELECT" range="2">
|
|
// <info>
|
|
// RESERVED. This bit is not implemented on X4xx and reads as 0.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="REFCLK_LOCKED" range="3" writable="false">
|
|
// <info>
|
|
// RESERVED. This bit is not implemented on X4xx and reads as 0.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="TRIGGER_IO_SELECT" range="5..4" initialvalue="TRIG_IO_INPUT">
|
|
// <info>
|
|
// <b>IMPORTANT!</b> SW must ensure any TRIG_IO consumers (downstream devices) <b>ignore
|
|
// and/or re-sync after enabling this port</b>, since the output-enable is basically
|
|
// asynchronous to the actual TRIG_IO driver.
|
|
// </info>
|
|
// <enumeratedtype name="TRIG_IO_ENUM">
|
|
// <value name="TRIG_IO_INPUT" integer="0"/>
|
|
// <value name="TRIG_IO_PPS_OUTPUT" integer="1"/>
|
|
// </enumeratedtype>
|
|
// <info>
|
|
// Select the direction and content of the trigger inout signal.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="PLL_SYNC_TRIGGER" range="8" readable="false">
|
|
// <info>
|
|
// Assertion triggers the SYNC signal generation for LMK04832 after the next appearance of the PPS rising edge.
|
|
// There is no self reset on this trigger.
|
|
// Keep this trigger asserted until @.PLL_SYNC_DONE is asserted.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="PLL_SYNC_DONE" range="9" writable="false">
|
|
// <info>Indicates the success of the PLL reset started by @.PLL_SYNC_TRIGGER. Reset on deassertion of @.PLL_SYNC_TRIGGER.</info>
|
|
// </bitfield>
|
|
// <bitfield name="PLL_SYNC_DELAY" range="16..23">
|
|
// <info>
|
|
// Due to the HDL implementation the rising edge of the SYNC signal for
|
|
// the LMK04832 is generated 2 clock cycles after the PPS rising edge.
|
|
// This delay can be further increased by setting this delay value
|
|
// (e.g. PLL_SYNC_DELAY=3 will result in a total delay of 5 clock cycles).<br>
|
|
// In case two X400 devices are connected using the PPS and reference clock the master delay value needs to be 3 clock cycles
|
|
// higher than the slave delay value to align the LMK sync edges in time.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="PPS_BRC_DELAY" range="31..24">
|
|
// <info>
|
|
// Number of base reference clock cycles from appearance of the PPS
|
|
// rising edge to the occurrence of the aligned edge of base reference
|
|
// clock and PLL reference clock at the sample PLL output. This number
|
|
// is the sum of the actual value based on @.PLL_SYNC_DELAY (also
|
|
// accumulate the fixed amount of clock cycles) and if any the number of
|
|
// cycles the SPLL requires from issuing of the SYNC signal to the
|
|
// aligned edge (with LMK04832 = 0).<br>
|
|
// The number written to this register has to be reduced by 1 due to
|
|
// HDL implementation.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="PPS_CTRL_REG" offset="0x1C" size="32">
|
|
// <info>Control registers for PPS generation.</info>
|
|
// <bitfield name="PPS_PRC_DELAY" range="25..0">
|
|
// <info>
|
|
// The number of PLL reference clock cycles from one aligned edge to the
|
|
// desired aligned edge to issue the PPS in radio clock domain. This
|
|
// delay is configurable to any aligned edge within a maximum delay of 1
|
|
// second (period of PPS). <br>
|
|
// The value written to the register has to be reduced by 4 due to
|
|
// HDL implementation.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="PRC_RC_DIVIDER" range="29..28">
|
|
// <info>
|
|
// Clock multiplier used to generate radio clock from PLL reference clock.
|
|
// The value written to the register has to be reduced by 2 due to
|
|
// HDL implementation.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="PPS_RC_ENABLED" range="31">
|
|
// <info>
|
|
// Enables the PPS signal in radio clock domain. Please make sure that
|
|
// the values of @.PPS_BRC_DELAY, @.PPS_PRC_DELAY and @.PRC_RC_DIVIDER are
|
|
// set before enabling this bit. It is recommended to disable the PPS
|
|
// for changes on the other values. Use a wait time of at least 1 second
|
|
// before changing this value to ensure the values are stable for the
|
|
// next PPS edge.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="CHDR_CLK_RATE_REG" offset="0x20" size="32" writable="false">
|
|
// <info>Returns the RFNoC bus clock rate (CHDR).</info>
|
|
// <bitfield name="CHDR_CLK" range="31..0" initialvalue="CHDR_CLK_VALUE">
|
|
// <enumeratedtype name="CHDR_CLK_ENUM" showhex="true">
|
|
// <value name="CHDR_CLK_VALUE" integer="200000000"/>
|
|
// </enumeratedtype>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="CHDR_CLK_COUNT_REG" offset="0x24" size="32" writable="false">
|
|
// <info>
|
|
// Returns the count value of a free-running counter driven by the RFNoC
|
|
// CHDR bus clock.
|
|
// </info>
|
|
// </register>
|
|
// <register name="BUILD_SEED_REG" offset="0x28" size="32" writable="false">
|
|
// <info>
|
|
// Build seed used for this compilation. Making this value readable
|
|
// ensures that compilation results are affected by the value in this
|
|
// register.
|
|
// </info>
|
|
// </register>
|
|
// <register name="QSFP_PORT_0_0_INFO_REG" offset="0x60" size="32" writable="false">
|
|
// <info>
|
|
// Returns information from the QSFP0 Lane0.
|
|
// </info>
|
|
// </register>
|
|
// <register name="QSFP_PORT_0_1_INFO_REG" offset="0x64" size="32" writable="false">
|
|
// <info>
|
|
// Returns information from the QSFP0 Lane1.
|
|
// </info>
|
|
// </register>
|
|
// <register name="QSFP_PORT_0_2_INFO_REG" offset="0x68" size="32" writable="false">
|
|
// <info>
|
|
// Returns information from the QSFP0 Lane2.
|
|
// </info>
|
|
// </register>
|
|
// <register name="QSFP_PORT_0_3_INFO_REG" offset="0x6C" size="32" writable="false">
|
|
// <info>
|
|
// Returns information from the QSFP0 Lane3.
|
|
// </info>
|
|
// </register>
|
|
// <register name="QSFP_PORT_1_0_INFO_REG" offset="0x70" size="32" writable="false">
|
|
// <info>
|
|
// Returns information from the QSFP1 Lane0.
|
|
// </info>
|
|
// </register>
|
|
// <register name="QSFP_PORT_1_1_INFO_REG" offset="0x74" size="32" writable="false">
|
|
// <info>
|
|
// Returns information from the QSFP1 Lane1.
|
|
// </info>
|
|
// </register>
|
|
// <register name="QSFP_PORT_1_2_INFO_REG" offset="0x78" size="32" writable="false">
|
|
// <info>
|
|
// Returns information from the QSFP1 Lane2.
|
|
// </info>
|
|
// </register>
|
|
// <register name="QSFP_PORT_1_3_INFO_REG" offset="0x7C" size="32" writable="false">
|
|
// <info>
|
|
// Returns information from the QSFP1 Lane3.
|
|
// </info>
|
|
// </register>
|
|
// <register name="GPS_CTRL_REG" offset="0x38" size="32">
|
|
// <info>
|
|
// RESERVED. This register is not implemented on X4xx. GPS is connected
|
|
// to the PS via a UART.
|
|
// </info>
|
|
// </register>
|
|
// <register name="GPS_STATUS_REG" offset="0x3C" size="32" writable="false">
|
|
// <info>
|
|
// RESERVED. This register is not implemented on X4xx. GPS is connected
|
|
// to the PS via a UART.
|
|
// </info>
|
|
// </register>
|
|
// <register name="DBOARD_CTRL_REG" offset="0x40" size="32">
|
|
// <info>
|
|
// RESERVED. This register is not implemented on X4xx.
|
|
// </info>
|
|
// </register>
|
|
// <register name="DBOARD_STATUS_REG" offset="0x44" size="32" writable="false">
|
|
// <info>
|
|
// RESERVED. This register is not implemented on X4xx.
|
|
// </info>
|
|
// </register>
|
|
// <register name="NUM_TIMEKEEPERS_REG" offset="0x48" size="32" writable="false">
|
|
// <info>Register that specifies the number of timekeepers in the core.</info>
|
|
// </register>
|
|
// <register name="SERIAL_NUM_LOW_REG" offset="0x4C" size="32">
|
|
// <info>Least significant bytes of 8 byte serial number</info>
|
|
// </register>
|
|
// <register name="SERIAL_NUM_HIGH_REG" offset="0x50" size="32">
|
|
// <info>Most significant bytes of 8 byte serial number</info>
|
|
// </register>
|
|
// <register name="MFG_TEST_CTRL_REG" offset="0x54" size="32">
|
|
// <info>Control register for mfg_test functions.</info>
|
|
// <bitfield name="MFG_TEST_EN_GTY_RCV_CLK" range="0">
|
|
// <info>
|
|
// When enabled, routes data_clk to GTY_RCV_CLK output port.
|
|
// When disabled, the GTY_RCV_CLK output is driven to 0.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="MFG_TEST_EN_FABRIC_CLK" range="1">
|
|
// <info>
|
|
// When enabled, routes data_clk to FPGA_REF_CLK output port.
|
|
// When disabled, the FPGA_REF_CLK output is driven to 0.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="MFG_TEST_STATUS_REG" offset="0x58" size="32">
|
|
// <info>Status register for mfg_test functions.</info>
|
|
// <bitfield name="MFG_TEST_FPGA_AUX_REF_FREQ" range="25..0">
|
|
// <info>
|
|
// Report the time between rising edges on the FPGA_REF_CLK
|
|
// input port in 40 MHz Clock ticks. If the count extends
|
|
// to 1.2 seconds without an edge, the value reported is set
|
|
// to zero.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// </group>
|
|
//</regmap>
|
|
//XmlParse xml_off
|