fpga: x400: Add support for X410 motherboard FPGA

Co-authored-by: Andrew Moch <Andrew.Moch@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Javier Valenzuela <javier.valenzuela@ni.com>
Co-authored-by: Joerg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Kumaran Subramoniam <kumaran.subramoniam@ni.com>
Co-authored-by: Max Köhler <max.koehler@ni.com>
Co-authored-by: Michael Auchter <michael.auchter@ni.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>
Co-authored-by: Hector Rubio <hrubio@ni.com>


Original-commit: 6d3765605262016a80f71e36357f749ea35cbe5a
This commit is contained in:
Wade Fife
2021-06-10 11:56:58 -05:00
committed by Aaron Rossetto
co-authored by Andrew Moch Daniel Jepson Javier Valenzuela Joerg Hofrichter Kumaran Subramoniam Max Köhler Michael Auchter Paul Butler Hector Rubio
parent bfef20ea45
commit 61782b02d7
205 changed files with 299634 additions and 0 deletions
+267
View File
@@ -0,0 +1,267 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: x4xx_versioning_regs
//
// Description:
//
// This module contains the motherboard registers for tracking
// HDL components versions.
//
// This versioning module is comprised of up to 256 read-only registers,
// which provide versioning information for up to 64 components (256/4).
// Each component has 3 x 32-bit registers for the following purpose:
// - Current version
// - Oldest compatible version
// - Last modified time stamp
//
// Note that in order to facilitate implementation, each component
// allocates a 4th register address (Reserved) for future use.
//
// Allocation of the 64 addressable components is shown below.
// This allocation determines the definition of COMPONENTS_INDEXES
// in the register map documentation below.
//
// --- Common components ---
// Reserved space for up to 24 components.
// - FPGA
// - MB CPLD interface
// - RF core (db 0)
// - RF core (db 1)
// - GPIO interface (db 0)
// - GPIO interface (db 1)
//
// --- UHD-specific components ---
// Reserved space for up to 20 components.
// - QSFP wrapper (port 0)
// - QSFP wrapper (port 1)
//
// --- LV-specific components ---
// Reserved space for up to 20 components.
//
// Parameters:
//
// REG_BASE : Base address to use for registers.
//
`default_nettype none
module x4xx_versioning_regs #(
parameter REG_BASE = 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}},
// Version (Constant)
// Each component consists of a 96-bit vector (refer to versioning_utils.vh)
input wire [64*96-1:0] version_info
);
`include "regmap/versioning_regs_regmap_utils.vh"
`include "regmap/versioning_utils.vh"
`include "../../lib/rfnoc/core/ctrlport.vh"
// 64 components * 4 registers * 4 addresses p/ register
localparam REG_SIZE = MAX_NUM_OF_COMPONENTS*4*4;
//--------------------------------------------------------------------
// Versioning 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);
// Mask out 6 bits (64 components) to be able to compare all components
// against the same base register address.
wire [31:0] register_base_address = {s_ctrlport_req_addr[19:10], 6'b0, s_ctrlport_req_addr[3:0]};
// Extract masked out bits from the address, which represent the
// component that is being addressed (0-63) = 6 bits.
wire [ 5:0] component_index = s_ctrlport_req_addr[9:4];
// Obtain the indexed component's versions
wire [COMPONENT_VERSIONS_SIZE-1:0] component_versions = get_component_versions(version_info, component_index);
// Registers implementation
always @ (posedge s_ctrlport_clk) begin
if (s_ctrlport_rst) begin
s_ctrlport_resp_ack <= 1'b0;
s_ctrlport_resp_status <= 2'b00;
s_ctrlport_resp_data <= {32 {1'bX}};
end else begin
// Write registers
if (s_ctrlport_req_wr) begin
// Do not acknowledge by default
s_ctrlport_resp_ack <= 1'b0;
s_ctrlport_resp_data <= 32'h0;
// No writable registers
// Acknowledge and provide error status if address is in range
if (address_in_range) begin
s_ctrlport_resp_ack <= 1'b1;
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
end
// 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 (register_base_address)
// Each concatenated 96-bit vector contains 3 x 32-bit values:
// [31: 0] -> Current version
// [63:32] -> Oldest compatible version
// [95:64] -> Last modified
REG_BASE + CURRENT_VERSION(0): begin
s_ctrlport_resp_data[VERSION_TYPE_SIZE-1:0] <= current_version(component_versions);
end
REG_BASE + OLDEST_COMPATIBLE_VERSION(0): begin
s_ctrlport_resp_data[VERSION_TYPE_SIZE-1:0] <= oldest_compatible_version(component_versions);
end
REG_BASE + VERSION_LAST_MODIFIED(0): begin
s_ctrlport_resp_data[TIMESTAMP_TYPE_SIZE-1:0] <= version_last_modified(component_versions);
end
// Do not acknowledge if address is not defined
default: begin
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
endmodule
`default_nettype wire
//XmlParse xml_on
//<regmap name="VERSIONING_REGS_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
// <group name="VERSIONING_REGS">
// <regtype name="VERSION_TYPE" size="32" attributes="Readable">
// <bitfield name="MAJOR" range="31..23" initialvalue="0">
// <info>
// Major number (max = 511): an increase reflects a breaking change.{BR/}
// <b>IMPORTANT!</b> @.MAJOR must always remain in sync between the component's
// @.CURRENT_VERSION and @.OLDEST_COMPATIBLE_VERSION registers.{BR/}{BR/}
// Update @.MAJOR when:
// <li>the component has changed and requires a software changes as a result.
// <li>the component's bitfields/registers have been modified or deleted.
// <li>the component's bitfields/registers are initialized to different value (unexpected by software).
// <li>new bitfields/registers are added that require software interaction for the component to operate.
// </info>
// </bitfield>
// <bitfield name="MINOR" range="22..12" initialvalue="0">
// <info>
// Minor number (max = 2047): an increase reflects a non-breaking change that the driver should be aware of.{BR/}{BR/}
// Update @.MINOR when:
// <li>a new feature is added to the component, which does not conflict with the driver.
// <li>minor implementation changes were made to the component which are worth tracking.
// <li>the component has added new bitfields/registers that do not require software interaction
// (i.e. the default value is 0 and writing 0 does not change behavior, assuming SW writes 0's to
// previously undefined bits).
// <li>@.MAJOR is updated (reset @.MINOR to 0).
// </info>
// </bitfield>
// <bitfield name="BUILD" range="11..0" initialvalue="0">
// <info>
// Build number (max = 4095): an increase reflects a change in the source code that yields a new implementation,
// but that should not impact the component's behavior {BR/}
// Eventually, this number is intended to be automatically incremented for any new build.{BR/}{BR/}
// Meanwhile, update @.BUILD when:
// <li>the component's source code changes are not captured by @.MAJOR or @.MINOR.
// <li>@.MINOR or @.MAJOR are updated (reset @.BUILD to 0).
// </info>
// </bitfield>
// </regtype>
// <regtype name="TIMESTAMP_TYPE" size="32" attributes="Readable">
// <info>
// Component's versions update time.{BR/}
// This register provides the time stamp for the last modification to
// the component's versions (current & oldest compatible).
// The time stamp is provided in hexadecimal format: 0xYYMMDDHH.
// </info>
// <bitfield name="YY" range="31..24">
// <info>This is the year number after 2000 (e.g. 2019 = 0x19).</info>
// </bitfield>
// <bitfield name="MM" range="23..16"/>
// <bitfield name="DD" range="15..8"/>
// <bitfield name="HH" range="7..0"/>
// </regtype>
// <regtype name="RESERVED_TYPE" size="32" attributes="Readable">
// <info>
// Reserved.
// </info>
// </regtype>
//
// <enumeratedtype name="COMPONENTS_INDEXES">
// <info>
// This enum contains indexes for all the components in the X410
// (both common and app-specific) which version information is
// desired to be available for compatibility tracking purposes.{BR/}
// {table border="1"}
// {tr}{th}Description{/th} {th}Index range{/th} {th}Max # of components{/th}{/tr}
// {tr}{td}Common components{/td} {td}0 to 23{/td} {td}24{/td}{/tr}
// {tr}{td}UHD-specific components{/td} {td}24 to 43{/td} {td}20{/td}{/tr}
// {tr}{td}LV-specific components{/td} {td}44 to 63{/td} {td}20{/td}{/tr}
// {/table}
// </info>
// <value name="FPGA_VERSION_INDEX" integer="0"/>
// <value name="CPLD_IFC_INDEX" integer="1"/>
// <value name="DB0_RF_CORE_INDEX" integer="2"/>
// <value name="DB1_RF_CORE_INDEX" integer="3"/>
// <value name="DB0_GPIO_IFC_INDEX" integer="4"/>
// <value name="DB1_GPIO_IFC_INDEX" integer="5"/>
// </enumeratedtype>
//
// <register name="CURRENT_VERSION" offset="0x0" count="64" step="16" typename="VERSION_TYPE">
// <info>
// Component's current version.{BR/}
// This register contains the current component's version implemented in HDL.
// The current version shall be used to detect a component being too
// old for the driver/software:{BR/}
// <b>SW oldest compatible version > Component's current version --> Component is too old.</b>
// </info>
// </register>
// <register name="OLDEST_COMPATIBLE_VERSION" offset="0x4" count="64" step="16" typename="VERSION_TYPE">
// <info>
// Component's oldest compatible version.{BR/}
// This register contains the oldest compatible component's version, that is the oldest
// component's implementation that is compatible with the current implementation.{BR/}
// The oldest compatible version shall be used to detect a component being too
// new for the driver/software:{BR/}
// <b>SW current version < Component's oldest compatible version --> Component is too new.</b>
// </info>
// </register>
// <register name="VERSION_LAST_MODIFIED" offset="0x8" count="64" step="16" typename="TIMESTAMP_TYPE"/>
// <register name="RESERVED" offset="0xC" count="64" step="16" typename="RESERVED_TYPE"/>
//
// </group>
//</regmap>
//XmlParse xml_off