// // Copyright 2021 Ettus Research, A National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // // Module: ps_cpld_regs // // Description: // // Basic registers to inform software about version and capabilities. // // Parameters: // // BASE_ADDRESS : Base address for CtrlPort registers // `default_nettype none module ps_cpld_regs #( parameter BASE_ADDRESS = 0 ) ( input wire ctrlport_clk, input wire ctrlport_rst, // Request 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, // Response output reg s_ctrlport_resp_ack, output reg [ 1:0] s_ctrlport_resp_status, output reg [31:0] s_ctrlport_resp_data, // Configuration outputs output reg [ 1:0] db_clk_enable = 2'b00, output reg [ 1:0] db_reset = 2'b11, output reg pll_ref_clk_enable = 1'b0, output reg [11:0] dio_direction_a = 12'b0, output reg [11:0] dio_direction_b = 12'b0, output reg [39:0] serial_num = 40'b0, output reg cmi_ready = 1'b0, input wire cmi_other_side_detected ); `include "regmap/constants_regmap_utils.vh" `include "regmap/ps_cpld_base_regmap_utils.vh" `include "../../../lib/rfnoc/core/ctrlport.vh" //----------------------------------------------------------------------------- // Address Calculation //----------------------------------------------------------------------------- localparam NUM_ADDRESSES = 64; wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) && (s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES); //----------------------------------------------------------------------------- // Internal Registers //----------------------------------------------------------------------------- reg [SCRATCH_REGISTER_SIZE-1:0] scratch_reg; //----------------------------------------------------------------------------- // Handling of ControlPort Requests //----------------------------------------------------------------------------- always @(posedge ctrlport_clk) begin // Reset internal registers and responses if (ctrlport_rst) begin scratch_reg <= 0; db_clk_enable <= 2'b00; db_reset <= 2'b11; pll_ref_clk_enable <= 1'b0; dio_direction_a <= {DIO_DIRECTION_A_SIZE{1'b0}}; dio_direction_b <= {DIO_DIRECTION_B_SIZE{1'b0}}; s_ctrlport_resp_ack <= 1'b0; s_ctrlport_resp_data <= {CTRLPORT_ADDR_W {1'bx}}; s_ctrlport_resp_status <= CTRL_STS_OKAY; // Write requests end else begin if (s_ctrlport_req_wr) begin // Always issue an ack and no data s_ctrlport_resp_ack <= 1'b1; s_ctrlport_resp_data <= {CTRLPORT_ADDR_W {1'bx}}; s_ctrlport_resp_status <= CTRL_STS_OKAY; case (s_ctrlport_req_addr) BASE_ADDRESS + SCRATCH_REGISTER: scratch_reg <= s_ctrlport_req_data; BASE_ADDRESS + PL_DB_REGISTER: begin if (s_ctrlport_req_data[DISABLE_CLOCK_DB0]) begin db_clk_enable[0] <= 1'b0; end else if (s_ctrlport_req_data[ENABLE_CLOCK_DB0]) begin db_clk_enable[0] <= 1'b1; end if (s_ctrlport_req_data[DISABLE_CLOCK_DB1]) begin db_clk_enable[1] <= 1'b0; end else if (s_ctrlport_req_data[ENABLE_CLOCK_DB1]) begin db_clk_enable[1] <= 1'b1; end if (s_ctrlport_req_data[DISABLE_PLL_REF_CLOCK]) begin pll_ref_clk_enable <= 1'b0; end else if (s_ctrlport_req_data[ENABLE_PLL_REF_CLOCK]) begin pll_ref_clk_enable <= 1'b1; end if (s_ctrlport_req_data[ASSERT_RESET_DB0]) begin db_reset[0] <= 1'b1; end else if (s_ctrlport_req_data[RELEASE_RESET_DB0]) begin db_reset[0] <= 1'b0; end if (s_ctrlport_req_data[ASSERT_RESET_DB1]) begin db_reset[1] <= 1'b1; end else if (s_ctrlport_req_data[RELEASE_RESET_DB1]) begin db_reset[1] <= 1'b0; end end BASE_ADDRESS + DIO_DIRECTION_REGISTER: begin dio_direction_a <= s_ctrlport_req_data[DIO_DIRECTION_A_MSB:DIO_DIRECTION_A]; dio_direction_b <= s_ctrlport_req_data[DIO_DIRECTION_B_MSB:DIO_DIRECTION_B]; end BASE_ADDRESS + SERIAL_NUM_LOW_REG: begin serial_num[31:0] <= s_ctrlport_req_data; end BASE_ADDRESS + SERIAL_NUM_HIGH_REG: begin serial_num[39:32] <= s_ctrlport_req_data[SERIAL_NUM_HIGH_REG_SIZE-1:0]; end BASE_ADDRESS + CMI_CONTROL_STATUS: begin cmi_ready <= s_ctrlport_req_data[CMI_READY]; end // Error on undefined address 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 // Read request end else if (s_ctrlport_req_rd) begin // Default assumption: valid request s_ctrlport_resp_ack <= 1'b1; s_ctrlport_resp_status <= CTRL_STS_OKAY; s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}}; case (s_ctrlport_req_addr) BASE_ADDRESS + SIGNATURE_REGISTER: s_ctrlport_resp_data <= PS_CPLD_SIGNATURE; BASE_ADDRESS + REVISION_REGISTER: s_ctrlport_resp_data <= CPLD_REVISION; BASE_ADDRESS + OLDEST_COMPATIBLE_REVISION_REGISTER: s_ctrlport_resp_data <= OLDEST_CPLD_REVISION; BASE_ADDRESS + SCRATCH_REGISTER: s_ctrlport_resp_data <= scratch_reg; BASE_ADDRESS + GIT_HASH_REGISTER: `ifdef GIT_HASH s_ctrlport_resp_data <= `GIT_HASH; `else s_ctrlport_resp_data <= 32'hDEADBEEF; `endif BASE_ADDRESS + PL_DB_REGISTER: begin s_ctrlport_resp_data[DB0_CLOCK_ENABLED] <= db_clk_enable[0]; s_ctrlport_resp_data[DB1_CLOCK_ENABLED] <= db_clk_enable[1]; s_ctrlport_resp_data[PLL_REF_CLOCK_ENABLED] <= pll_ref_clk_enable; s_ctrlport_resp_data[DB0_RESET_ASSERTED] <= db_reset[0]; s_ctrlport_resp_data[DB1_RESET_ASSERTED] <= db_reset[1]; end BASE_ADDRESS + DIO_DIRECTION_REGISTER: begin s_ctrlport_resp_data[DIO_DIRECTION_A_MSB:DIO_DIRECTION_A] <= dio_direction_a; s_ctrlport_resp_data[DIO_DIRECTION_B_MSB:DIO_DIRECTION_B] <= dio_direction_b; end BASE_ADDRESS + SERIAL_NUM_LOW_REG: begin s_ctrlport_resp_data <= serial_num[31:0]; end BASE_ADDRESS + SERIAL_NUM_HIGH_REG: begin s_ctrlport_resp_data[SERIAL_NUM_HIGH_REG_SIZE-1:0] <= serial_num[39:32]; end BASE_ADDRESS + CMI_CONTROL_STATUS: begin s_ctrlport_resp_data[CMI_READY] <= cmi_ready; s_ctrlport_resp_data[OTHER_SIDE_DETECTED] <= cmi_other_side_detected; end // Error on undefined address default: begin s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'bx}}; 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 // No request end else begin s_ctrlport_resp_ack <= 1'b0; end end end endmodule `default_nettype wire //XmlParse xml_on // // // // Basic registers containing version and capabilites information. // // // // Contains the product's signature. // // Fixed value PS_CPLD_SIGNATURE of @.CONSTANTS_REGMAP // // // // // Contains the CPLD revision (see CPLD_REVISION of @.CONSTANTS_REGMAP). // // Contains revision hour code. // // // Contains revision day code. // // // Contains revision month code. // // // Contains revision year code. // // // // // // This register returns (in YYMMDDHH format) the oldest revision // that is still compatible with this one. Compatible means that // registers or register bits may have been added, but not // modified or deleted (see OLDEST_CPLD_REVISION of @.CONSTANTS_REGMAP). // // // Contains revision hour code. // // // Contains revision day code. // // // Contains revision month code. // // // Contains revision year code. // // // // // Read/write register for general software use. // // // // // Git hash of commit used to build this image.{br} // Value equals 0xDEADBEEF if the git hash was not used during synthesis. // // // // 0x0 in case the git status was clean{br} // 0xF in case there were uncommitted changes // // // // 7 hex digit hash code of the commit // // // // // // // Register Map to control MB CPLD functions. // // // // Register to control the PL part DB SPI connection and reset generation. // The DB connection is clocked with PLL reference clock. Ensure this clock is stable // and enabled before starting any SPI request. // The PLL reference clock can be disabled if both DB connections are disabled or inactive. // To enable the DB connection, enable clock with one write access and release // reset with the next write access. // To disable the DB connection, assert reset with one write access and // disable clocks with the next write access. // // // Indicates if a clock is forwarded to DB 0. // // // Indicates if a clock is forwarded to DB 1. // // // Indicates if the PLL reference clock for the PL interface is enabled. // // // Indicates that reset is asserted for DB 0. // // // Indicates that reset is asserted for DB 1. // // // Writing with this flag set enables DB 0 clock forwarding. (may be overwritten by @.DISABLE_CLOCK_DB0) // // // Writing with this flag set enables DB 1 clock forwarding. (may be overwritten by @.DISABLE_CLOCK_DB1) // // // Writing with this flag set enables the PLL reference clock. Assert this flag after PLL reference clock is stable. (may be overwritten by @.DISABLE_PLL_REF_CLOCK) // // // Writing with this flag set disables DB 0 clock forwarding (overrides @.ENABLE_CLOCK_DB0) // // // Writing with this flag set disables DB 1 clock forwarding (overrides @.ENABLE_CLOCK_DB1) // // // Writing with this flag set disables the PLL reference clock (overrides @.ENABLE_PLL_REF_CLOCK). Assert this flag to reconfigure the clock. // // // Writing with this flag set releases DB 0 reset. (may be overwritten by @.ASSERT_RESET_DB0) // // // Writing with this flag set releases DB 1 reset. (may be overwritten by @.ASSERT_RESET_DB1) // // // Writing with this flag set asserts reset for DB 0 (overrides @.RELEASE_RESET_DB0) // // // Writing with this flag set asserts reset for DB 1 (overrides @.RELEASE_RESET_DB1) // // // // // // // Registers to control the GPIO buffer direction on the DIO board connected to the FPGA. // Make sure the GPIO lines between FPGA and GPIO board are not driven by two drivers. // Set the direction in the FPGA's DIO register appropriately. // // // // Set the direction of FPGA buffer connected to DIO ports on the DIO board.{br/} // Each bit represents one signal line. 0 = line is an input to the FPGA, 1 = line is an output driven by the FPGA. // // // // // // // // // Cable present status register. // // // Least significant bytes of 5 byte serial number. // // // Most significant byte of 5 byte serial number. // // // Control CMI communication and delivers information on the CMI link status. // // Set if the device is ready to establish a PCI-Express link (affects CMI_CLP_READY bit). // // // 1 if an upstream CMI device has been detected. // // // // //XmlParse xml_off