fpga: x400: Set QSFP LEDs on startup
Original-commit: 977b842584a11f94bd635d1b4181e90494e0e8e1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2021 Ettus Research, A National Instruments Brand
|
// Copyright 2023 Ettus Research, a National Instruments Brand
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
//
|
//
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
//
|
//
|
||||||
// Translate the CLIP active and link LED signals on FPGA to control port
|
// Translate the active and link status LED signals on FPGA to control port
|
||||||
// requests in order to transfer them to the CPLD, which drives the LEDs
|
// requests in order to transfer them to the CPLD, which drives the LEDs.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
//
|
//
|
||||||
@@ -44,6 +44,8 @@ module qsfp_led_controller #(
|
|||||||
input wire [3:0] qsfp1_led_link
|
input wire [3:0] qsfp1_led_link
|
||||||
);
|
);
|
||||||
|
|
||||||
|
`include "../../lib/rfnoc/core/ctrlport.vh"
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Transfer LED signals to local clock domain
|
// Transfer LED signals to local clock domain
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@@ -63,32 +65,69 @@ module qsfp_led_controller #(
|
|||||||
);
|
);
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Logic to wait for response after trigging request
|
// State machine to initialize and update LED status
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
|
|
||||||
reg transfer_in_progress;
|
localparam COUNT_W = 8;
|
||||||
|
localparam MAX_COUNT = 2**COUNT_W-1;
|
||||||
|
|
||||||
|
// This counter ensures the we have a delay before we attempt to initialize
|
||||||
|
// the LED state and limits the rate at which the LEDs update.
|
||||||
|
reg [COUNT_W-1:0] startup_count = 0;
|
||||||
|
|
||||||
|
localparam ST_INIT = 0;
|
||||||
|
localparam ST_WRITE = 1;
|
||||||
|
localparam ST_WAIT_ACK = 2;
|
||||||
|
localparam ST_IDLE = 3;
|
||||||
|
|
||||||
|
reg [1:0] state = ST_INIT;
|
||||||
|
|
||||||
reg [15:0] led_combined_delayed;
|
reg [15:0] led_combined_delayed;
|
||||||
|
|
||||||
always @(posedge ctrlport_clk) begin
|
always @(posedge ctrlport_clk) begin
|
||||||
|
m_ctrlport_req_wr <= 0;
|
||||||
|
led_combined_delayed <= led_combined;
|
||||||
|
|
||||||
|
case (state)
|
||||||
|
ST_INIT : begin
|
||||||
|
// Set LED state after a delay
|
||||||
|
startup_count <= startup_count + 1;
|
||||||
|
if (startup_count == MAX_COUNT) begin
|
||||||
|
state <= ST_WRITE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_WRITE : begin
|
||||||
|
// Start an LED update request
|
||||||
|
m_ctrlport_req_wr <= 1;
|
||||||
|
state <= ST_WAIT_ACK;
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_WAIT_ACK : begin
|
||||||
|
// Wait for the acknowledgment from the bus
|
||||||
|
if (m_ctrlport_resp_ack) begin
|
||||||
|
if (m_ctrlport_resp_status != CTRL_STS_OKAY) begin
|
||||||
|
// Status was bad, so try again after a delay
|
||||||
|
state <= ST_INIT;
|
||||||
|
end else begin
|
||||||
|
state <= ST_IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_IDLE : begin
|
||||||
|
// Wait here until the LED status changes
|
||||||
|
if (led_combined != led_combined_delayed) begin
|
||||||
|
state <= ST_INIT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
if (ctrlport_rst) begin
|
if (ctrlport_rst) begin
|
||||||
m_ctrlport_req_wr <= 1'b0;
|
state <= ST_INIT;
|
||||||
transfer_in_progress <= 1'b0;
|
startup_count <= 0;
|
||||||
led_combined_delayed <= 16'b0;
|
m_ctrlport_req_wr <= 0;
|
||||||
end else begin
|
led_combined_delayed <= 0;
|
||||||
// Default assignment
|
|
||||||
m_ctrlport_req_wr <= 1'b0;
|
|
||||||
|
|
||||||
// Issue new request on change if no request is pending
|
|
||||||
if (led_combined != led_combined_delayed && ~transfer_in_progress) begin
|
|
||||||
transfer_in_progress <= 1'b1;
|
|
||||||
m_ctrlport_req_wr <= 1'b1;
|
|
||||||
led_combined_delayed <= led_combined;
|
|
||||||
end
|
|
||||||
|
|
||||||
// Reset pending request
|
|
||||||
if (m_ctrlport_resp_ack) begin
|
|
||||||
transfer_in_progress <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user