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