fpga: x4xx: Refactor MB CPLD code for future devices
Original-commit: e2a79712a7949ffec88135236c744dc5d8bde217
This commit is contained in:
committed by
Martin Braun
parent
e9a6fe4e2e
commit
ffdcc016cc
@@ -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
|
||||
Reference in New Issue
Block a user