diff options
Diffstat (limited to 'fpga/usrp3/top/x400/cpld/ps_power_regs.v')
-rw-r--r-- | fpga/usrp3/top/x400/cpld/ps_power_regs.v | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/fpga/usrp3/top/x400/cpld/ps_power_regs.v b/fpga/usrp3/top/x400/cpld/ps_power_regs.v new file mode 100644 index 000000000..3e1a25206 --- /dev/null +++ b/fpga/usrp3/top/x400/cpld/ps_power_regs.v @@ -0,0 +1,231 @@ +// +// Copyright 2021 Ettus Research, A National Instruments Brand +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: ps_power_regs +// +// Description: +// +// Registers to control power supplies on the motherboard. +// +// Parameters: +// +// BASE_ADDRESS : Base address for CtrlPort registers. +// NUM_ADDRESSES : Number of bytes of address space to use. +// + +`default_nettype none + + +module ps_power_regs #( + parameter BASE_ADDRESS = 0, + parameter NUM_ADDRESSES = 32 +) ( + 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, + + // iPass + output reg ipass_power_disable = 1'b0, + input wire [ 1:0] ipass_power_fault_n, + + // Oscillators + output reg osc_100_en, + output reg osc_122_88_en +); + + `include "regmap/ps_power_regmap_utils.vh" + `include "../../../lib/rfnoc/core/ctrlport.vh" + + //---------------------------------------------------------- + // Address Calculation + //---------------------------------------------------------- + + wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) && + (s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES); + + //---------------------------------------------------------- + // Internal Registers + //---------------------------------------------------------- + + reg [1:0] ipass_power_sticky = 2'b00; + reg [1:0] ipass_clear_sticky = 2'b00; + + //---------------------------------------------------------- + // Handling of ControlPort Requests + //---------------------------------------------------------- + + always @(posedge ctrlport_clk) begin + // Reset internal registers and responses + if (ctrlport_rst) begin + ipass_power_disable <= 1'b0; + s_ctrlport_resp_ack <= 1'b0; + s_ctrlport_resp_status <= CTRL_STS_OKAY; + s_ctrlport_resp_data <= {CTRLPORT_ADDR_W {1'bx}}; + + osc_100_en <= 1'b0; + osc_122_88_en <= 1'b0; + + end else begin + // Default assignments + ipass_clear_sticky <= 2'b00; + + // Write requests + if (s_ctrlport_req_wr) begin + // Always issue an ack and no data + s_ctrlport_resp_ack <= 1'b1; + s_ctrlport_resp_status <= CTRL_STS_OKAY; + s_ctrlport_resp_data <= {CTRLPORT_ADDR_W {1'bx}}; + + case (s_ctrlport_req_addr) + BASE_ADDRESS + IPASS_POWER_REG: begin + ipass_power_disable <= s_ctrlport_req_data[IPASS_DISABLE_POWER_BIT]; + ipass_clear_sticky[0] <= s_ctrlport_req_data[IPASS_CLEAR_POWER_FAULT0]; + ipass_clear_sticky[1] <= s_ctrlport_req_data[IPASS_CLEAR_POWER_FAULT1]; + end + + BASE_ADDRESS + OSC_POWER_REG: begin + osc_100_en <= s_ctrlport_req_data[OSC_100]; + osc_122_88_en <= s_ctrlport_req_data[OSC_122_88]; + 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 + IPASS_POWER_REG: begin + s_ctrlport_resp_data[IPASS_DISABLE_POWER_BIT] <= ipass_power_disable; + s_ctrlport_resp_data[IPASS_POWER_FAULT0] <= ipass_power_sticky[0]; + s_ctrlport_resp_data[IPASS_POWER_FAULT1] <= ipass_power_sticky[1]; + end + + BASE_ADDRESS + OSC_POWER_REG: begin + s_ctrlport_resp_data[OSC_100] <= osc_100_en; + s_ctrlport_resp_data[OSC_122_88] <= osc_122_88_en; + 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 + + //---------------------------------------------------------- + // Sticky Logic of Power Registers + //---------------------------------------------------------- + + // Synchronize asynchronous inputs + wire [1:0] ipass_power_fault_lcl_n; + synchronizer #( + .WIDTH (2), + .STAGES (2), + .INITIAL_VAL (1'b0), + .FALSE_PATH_TO_IN (1) + ) power_fault_sync ( + .clk (ctrlport_clk), + .rst (ctrlport_rst), + .in (ipass_power_fault_n), + .out (ipass_power_fault_lcl_n) + ); + + always @(posedge ctrlport_clk) begin + if (ctrlport_rst) begin + ipass_power_sticky <= 2'b00; + end else begin + // Keep value if not cleared or set in case of fault + ipass_power_sticky <= (ipass_power_sticky & ~ipass_clear_sticky) | ~ipass_power_fault_lcl_n; + end + end + +endmodule + + +`default_nettype wire + + +//XmlParse xml_on +//<regmap name="PS_POWER_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true"> +// <group name="PS_POWER_REGS"> +// <info> +// Registers to control power supplies on the motherboard. +// </info> +// +// <register name="IPASS_POWER_REG" offset="0x00" size="32"> +// <info>Controls the power supplies for the iPass connectors.</info> +// <bitfield name="IPASS_DISABLE_POWER_BIT" range="0"> +// <info>Set to 1 to disable power for both iPass connectors.</info> +// </bitfield> +// <bitfield name="IPASS_CLEAR_POWER_FAULT0" range="30" readable="false"> +// <info>Clear @.IPASS_POWER_FAULT0.</info> +// </bitfield> +// <bitfield name="IPASS_CLEAR_POWER_FAULT1" range="31" readable="false"> +// <info>Clear @.IPASS_POWER_FAULT1.</info> +// </bitfield> +// <bitfield name="IPASS_POWER_FAULT0" range="30" writable="false"> +// <info> +// Asserted signal indicates a power fault in power switch for iPass +// connector 0. Sticky bit. Asserted on occurrence. Reset using +// @.IPASS_CLEAR_POWER_FAULT0. +// </info> +// </bitfield> +// <bitfield name="IPASS_POWER_FAULT1" range="31" writable="false"> +// <info> +// Asserted signal indicates a power fault in power switch for iPass +// connector 1. Sticky bit. Asserted on occurrence. Reset using +// @.IPASS_CLEAR_POWER_FAULT1. +// </info> +// </bitfield> +// </register> +// +// <register name="OSC_POWER_REG" offset="0x04" size="32"> +// <info>Controls the power supplies for the oscillators.</info> +// <bitfield name="OSC_100" range="0"> +// <info>Enables 5V power switch for the 100 MHz oscillator.</info> +// </bitfield> +// <bitfield name="OSC_122_88" range="1"> +// <info>Enables 5V power switch for the 122.88 MHz oscillator.</info> +// </bitfield> +// </register> +// </group> +//</regmap> +//XmlParse xml_off |