aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/x400/cpld/ps_power_regs.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/x400/cpld/ps_power_regs.v')
-rw-r--r--fpga/usrp3/top/x400/cpld/ps_power_regs.v231
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