Skip to content
Snippets Groups Projects

Resolve L2SDP-1019

Merged Eric Kooistra requested to merge L2SDP-1019 into master
3 files
+ 438
4
Compare changes
  • Side-by-side
  • Inline
Files
3
-------------------------------------------------------------------------------
--
-- Copyright (C) 2024
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
-- Author: E. Kooistra
-- Purpose: Provide visual activity information via the UniBoard2 front panel QSFP LEDs.
-- Description:
-- The testio LED on UniBoard2 is not visible via the front panel. The
-- front panel does have a dual colour LED for each QSFP lane. Therefore
-- these QSFP LEDs are used to signal some application information and lane
-- status/activity information.
--
-- Comparison unb2c_board_qsfp_leds_v2 and unb2c_board_qsfp_leds:
-- . unb2c_board_qsfp_leds_v2 does not output the internal us, ms and s pulses,
-- because they depend on the clock domain and are typically left open with
-- unb2c_board_qsfp_leds
-- . For g_factory_image = false the unb2c_board_qsfp_leds_v2 = unb2c_board_qsfp_leds
-- except use dp_clk to detect the transceiver activity strobes.
-- . For g_factory_image = true unb2c_board_qsfp_leds_v2 also shows status of dp_clk,
-- dp_pps, and ddr_I_cal_ok, ddr_II_cal_ok
--
-- LED lights:
--
-- 1) Default behaviour for all QSFP leds:
-- . off = no FPGA image is running
--
-- 2) For factory image only use the red leds:
-- . green off
-- . red[0] on = factory image is running (g_factory_image=true)
-- off = no image is running
-- . red[1] toggling every 1 s = 125 MHz clock present (= mm_clk = clk)
-- . red[2] toggling every 1 s = pps present (= dp_pps)
-- . red[3] toggling every 1 s = 200 MHz clock present (= dp_clk)
-- . red[4] on = DDR4 bank I calibrated = ctlr_tech_miso.done in io_ddr
-- off = not calibrated or no DDR4 module present
-- . red[5] on = DDR4 bank II calibrated = ctlr_tech_miso.done in io_ddr
-- off = not calibrated or no DDR4 module present
--
-- 3) For a user image only use green leds:
-- . red off
--
-- a) without Gbps lane functionality:
-- . green toggling every 1 s = user image is running (g_factory_image=FALSE and green_on_arr(I)='0' default)
--
-- b) with Gbps lane functionality:
-- . green toggling every 1 s when the lane status is not OK (green_on_arr(I)=xon='0')
-- . green on continously when the lane status is OK (green_on_arr(I)=xon='1')
-- . green led goes off briefly off when there is an Tx or Rx packet (green_evt_arr(I).sop='1')
--
-- The combined colour amber (= red + green) is not used. The factory image
-- only uses the red led and the user image only uses the green led.
--
-- Each QSFP carries c_quad = 4 lanes, therefore the green led LED can only
-- signal a combined status of the lanes. The combined status eg. be:
--
-- 'and-status' = combined status is on when all lanes are on
-- 'or-status' = combined status is on when at least 1 lane is on
--
-- Choose using 'or-status', because then the LED can give lane status
-- information when less than all 4 lane are connected.
--
library IEEE, common_lib, dp_lib;
use IEEE.std_logic_1164.all;
use common_lib.common_pkg.all;
use dp_lib.dp_stream_pkg.all;
entity unb2c_board_qsfp_leds_v2 is
generic (
g_sim : boolean := false; -- when true speed up led toggling in simulation
g_factory_image : boolean := false; -- distinguish factory image and user images
g_nof_qsfp : natural := 6; -- number of QSFP cages each with one dual led that can light red or green (or amber = red + green)
g_mm_pulse_us : natural := 125; -- nof mm_clk cycles to get us period
g_dp_pulse_us : natural := 200 -- nof dp_clk cycles to get us period
);
port (
mm_rst : in std_logic;
mm_clk : in std_logic;
dp_rst : in std_logic := '0';
dp_clk : in std_logic := '0';
dp_pps : in std_logic := '0';
-- ddr status (level signals)
ddr_I_cal_ok : in std_logic := '0';
ddr_II_cal_ok : in std_logic := '0';
-- lane status (sop strobe signals in dp_clk domain)
tx_siso_arr : in t_dp_siso_arr(g_nof_qsfp * c_quad - 1 downto 0) := (others => c_dp_siso_rst);
tx_sosi_arr : in t_dp_sosi_arr(g_nof_qsfp * c_quad - 1 downto 0) := (others => c_dp_sosi_rst);
rx_sosi_arr : in t_dp_sosi_arr(g_nof_qsfp * c_quad - 1 downto 0) := (others => c_dp_sosi_rst);
-- leds
green_led_arr : out std_logic_vector(g_nof_qsfp - 1 downto 0);
red_led_arr : out std_logic_vector(g_nof_qsfp - 1 downto 0)
);
end unb2c_board_qsfp_leds_v2;
architecture str of unb2c_board_qsfp_leds_v2 is
constant c_nof_ms : natural := sel_a_b(g_sim, 1, 100); -- force off for c_nof_ms and then on for at least c_nof_ms
constant c_nof_lanes : natural := g_nof_qsfp * c_quad; -- number of transceiver lanes, fixed 4 per Quad-SFP cage
-- internal pulses
signal mm_pulse_s : std_logic; -- pulse 1 mm_clk cycle every 1 s
signal mm_toggle_s : std_logic; -- toggle every 1 s in mm_clk domain
signal dp_pulse_ms : std_logic; -- pulse 1 dp_clk cycle every 1 ms
signal dp_pulse_s : std_logic; -- pulse 1 dp_clk cycle every 1 us
signal dp_toggle_s : std_logic; -- toggle every 1 s in dp_clk domain
signal dp_toggle_pps : std_logic; -- pulse 1 dp_clk cycle every 1 s
signal green_on_arr : std_logic_vector(g_nof_qsfp * c_quad - 1 downto 0);
signal green_evt_arr : std_logic_vector(g_nof_qsfp * c_quad - 1 downto 0);
signal qsfp_on_arr : std_logic_vector(g_nof_qsfp - 1 downto 0);
signal qsfp_evt_arr : std_logic_vector(g_nof_qsfp - 1 downto 0);
begin
-- mm_clk domain pulsers
u_mm_common_pulser_us_ms_s : entity common_lib.common_pulser_us_ms_s
generic map (
g_pulse_us => g_mm_pulse_us, -- nof mm_clk cycles to get us period
g_pulse_ms => sel_a_b(g_sim, 10, 1000), -- nof pulse_us pulses to get ms period
g_pulse_s => sel_a_b(g_sim, 10, 1000) -- nof pulse_ms pulses to get s period
)
port map (
rst => mm_rst,
clk => mm_clk,
pulse_s => mm_pulse_s
);
u_mm_common_toggle_s : entity common_lib.common_toggle
port map (
rst => mm_rst,
clk => mm_clk,
in_dat => mm_pulse_s,
out_dat => mm_toggle_s
);
-- dp_clk domain pulsers
u_dp_common_pulser_us_ms_s : entity common_lib.common_pulser_us_ms_s
generic map (
g_pulse_us => g_dp_pulse_us, -- nof dp_clk cycles to get us period
g_pulse_ms => sel_a_b(g_sim, 10, 1000), -- nof pulse_us pulses to get ms period
g_pulse_s => sel_a_b(g_sim, 10, 1000) -- nof pulse_ms pulses to get s period
)
port map (
rst => dp_rst,
clk => dp_clk,
pulse_ms => dp_pulse_ms,
pulse_s => dp_pulse_s
);
u_dp_common_toggle_s : entity common_lib.common_toggle
port map (
rst => dp_rst,
clk => dp_clk,
in_dat => dp_pulse_s,
out_dat => dp_toggle_s
);
gen_factory_image : if g_factory_image = true generate
green_led_arr <= (others => '0');
red_led_arr(0) <= '1';
red_led_arr(1) <= mm_toggle_s;
red_led_arr(2) <= dp_toggle_pps;
red_led_arr(3) <= dp_toggle_s;
red_led_arr(4) <= ddr_I_cal_ok;
red_led_arr(5) <= ddr_II_cal_ok;
u_dp_common_toggle_pps : entity common_lib.common_toggle
port map (
rst => dp_rst,
clk => dp_clk,
in_dat => dp_pps,
out_dat => dp_toggle_pps
);
end generate;
gen_user_image : if g_factory_image = false generate
red_led_arr <= (others => '0');
gen_green_ctrl_arr : for I in c_nof_lanes - 1 downto 0 generate
green_on_arr(I) <= tx_siso_arr(I).xon when rising_edge(dp_clk);
green_evt_arr(I) <= tx_sosi_arr(I).sop or rx_sosi_arr(I).sop when rising_edge(dp_clk);
end generate;
gen_green_led_arr : for I in g_nof_qsfp - 1 downto 0 generate
qsfp_on_arr(I) <= orv(green_on_arr( (I + 1) * c_quad - 1 downto + I * c_quad));
qsfp_evt_arr(I) <= orv(green_evt_arr((I + 1) * c_quad - 1 downto + I * c_quad));
u_green_led_controller : entity common_lib.common_led_controller
generic map (
g_nof_ms => c_nof_ms
)
port map (
rst => dp_rst,
clk => dp_clk,
pulse_ms => dp_pulse_ms,
-- led control
ctrl_on => qsfp_on_arr(I),
ctrl_evt => qsfp_evt_arr(I),
ctrl_input => dp_toggle_s,
-- led output
led => green_led_arr(I)
);
end generate;
end generate;
end str;
Loading