Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com> Co-authored-by: Javier Valenzuela <javier.valenzuela@ni.com> Original-commit: 7015f5ed2d495f3908773b7c7d74864d0cc3871a
232 lines
7.3 KiB
Verilog
232 lines
7.3 KiB
Verilog
//
|
|
// 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
|