From f04310485efb625d3a79612e65891f3e0e9f893d Mon Sep 17 00:00:00 2001 From: Leon Hiemstra <hiemstra@astron.nl> Date: Thu, 27 Nov 2014 15:38:16 +0000 Subject: [PATCH] prepare unb2_minimal --- .../unb2_board/src/vhdl/ctrl_unb2_board.vhd | 668 ++++++++++++++++++ 1 file changed, 668 insertions(+) create mode 100644 boards/uniboard2/libraries/unb2_board/src/vhdl/ctrl_unb2_board.vhd diff --git a/boards/uniboard2/libraries/unb2_board/src/vhdl/ctrl_unb2_board.vhd b/boards/uniboard2/libraries/unb2_board/src/vhdl/ctrl_unb2_board.vhd new file mode 100644 index 0000000000..bdc9a05059 --- /dev/null +++ b/boards/uniboard2/libraries/unb2_board/src/vhdl/ctrl_unb2_board.vhd @@ -0,0 +1,668 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: Provide general control infrastructure +-- Usage: In a design <design_name>.vhd that consists of: +-- . sopc_<design_name>.vhd with a Nios2 and the MM bus and the peripherals +-- . ctrl_unb1_board.vhd with e.g. 1GbE and PPS +-- . node_<design_name>.vhd with the actual functionality of <design_name> + +LIBRARY IEEE, common_lib, dp_lib, ppsh_lib, i2c_lib, technology_lib, tech_tse_lib, eth_lib, remu_lib, epcs_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE work.unb1_board_pkg.ALL; +USE i2c_lib.i2c_pkg.ALL; +USE technology_lib.technology_pkg.ALL; +USE tech_tse_lib.tech_tse_pkg.ALL; +USE eth_lib.eth_pkg.ALL; + +ENTITY ctrl_unb1_board IS + GENERIC ( + ---------------------------------------------------------------------------- + -- General + ---------------------------------------------------------------------------- + g_technology : NATURAL := c_tech_stratixiv; + g_sim : BOOLEAN := FALSE; + g_design_name : STRING := "UNUSED"; + g_fw_version : t_unb1_board_fw_version := (0, 0); -- firmware version x.y + g_stamp_date : NATURAL := 0; + g_stamp_time : NATURAL := 0; + g_stamp_svn : NATURAL := 0; + g_design_note : STRING := "UNUSED"; + g_mm_clk_freq : NATURAL := c_unb1_board_mm_clk_freq_125M; -- default use same MM clock as for TSE clock + + ---------------------------------------------------------------------------- + -- External CLK + ---------------------------------------------------------------------------- + g_dp_clk_freq : NATURAL := c_unb1_board_ext_clk_freq_200M; + g_dp_clk_use_pll : BOOLEAN := TRUE; + -- PLL phase clk shift with respect to CLK + -- STRING := "0" = 0 + -- STRING := "156" = 011.25 + -- STRING := "313" = 022.5 + -- STRING := "469" = 033.75 + -- STRING := "625" = 045 + -- STRING := "781" = 056.25 + -- STRING := "938" = 067.5 + -- STRING := "1094" = 078.75 + -- STRING := "1250" = 090 + -- STRING := "1406" = 1250+ 156 = 101.25 + -- STRING := "1563" = 1250+ 313 = 112.5 + -- STRING := "1719" = 1250+ 469 = 123.75 + -- STRING := "1875" = 1250+ 625 = 135 + -- STRING := "2031" = 1250+ 781 = 146.25 + -- STRING := "2188" = 1250+ 938 = 157.5 + -- STRING := "2344" = 1250+1094 = 168.75 + -- STRING := "2500" = 1250+1250 = 180 + -- STRING := "2656" = 2500+ 156 = 191.25 + -- STRING := "2813" = 2500+ 313 = 202.5 + -- STRING := "2969" = 2500+ 469 = 213.75 + -- STRING := "3125" = 2500+ 625 = 225 + -- STRING := "3281" = 2500+ 781 = 236.25 + -- STRING := "3438" = 2500+ 938 = 247.5 + -- STRING := "3594" = 2500+1094 = 258.75 + -- STRING := "3750" = 2500+1250 = 270 + -- STRING := "3906" = 3750+ 156 = 281.25 + -- STRING := "4063" = 3750+ 313 = 292.5 + -- STRING := "4219" = 3750+ 469 = 303.75 + -- STRING := "4375" = 3750+ 625 = 315 + -- STRING := "4531" = 3750+ 781 = 326.25 + -- STRING := "4688" = 3750+ 938 = 337.5 + -- STRING := "4844" = 3750+1094 = 348.75 + -- STRING := "5000" = 3750+1250 = 360 + g_dp_clk_phase : STRING := "0"; -- phase offset for PLL c0, typically any phase is fine, do not use 225 +-30 degrees because there the PPS edge occurs + g_dp_phs_clk_vec_w : NATURAL := 0; -- >= 0 and <= 6, nof extra PLL output clocks dp_phs_clk_vec[5:0] = [c6, c5, c4, c3, c2, c1] + g_dp_phs_clk_divide_by : NATURAL := 32; -- divided by factor for dp_phs_clk_vec[5:0] + + ---------------------------------------------------------------------------- + -- Use PHY Interface + ---------------------------------------------------------------------------- + -- TYPE t_c_unb1_board_use_phy IS RECORD + -- eth1g : NATURAL; + -- eth10g : NATURAL; + -- tr_mesh : NATURAL; + -- tr_back : NATURAL; + -- ddr3_I : NATURAL; + -- ddr3_II : NATURAL; + -- adc : NATURAL; + -- wdi : NATURAL; + -- END RECORD; + g_use_phy : t_c_unb1_board_use_phy := (1, 0, 0, 0, 0, 0, 0, 1); + + ---------------------------------------------------------------------------- + -- 1GbE UDP offload + ---------------------------------------------------------------------------- + g_udp_offload : BOOLEAN := FALSE; + g_udp_offload_nof_streams : NATURAL := c_eth_nof_udp_ports; + + ---------------------------------------------------------------------------- + -- Auxiliary Interface + ---------------------------------------------------------------------------- + g_fpga_temp_high : NATURAL := 85; + g_app_led_red : BOOLEAN := FALSE; -- when TRUE use external LED control via app_led_red + g_dbg_led_red : BOOLEAN := FALSE; -- [when g_app_led_red=FALSE]: when TRUE connect pout_debug_wave to the LEDs; otherwise let ctrl_unb1_board toggle them + g_app_led_green : BOOLEAN := FALSE; -- when TRUE use external LED control via app_led_green + g_dbg_led_green : BOOLEAN := FALSE; -- [when g_app_led_green=FALSE]: when TRUE connect pout_debug_wave to the LEDs; otherwise let ctrl_unb1_board toggle them + + g_aux : t_c_unb1_board_aux := c_unb1_board_aux + ); + PORT ( + -- + -- >>> SOPC system with conduit peripheral MM bus + -- + -- System + cs_sim : OUT STD_LOGIC; + xo_clk : OUT STD_LOGIC; -- 25 MHz ETH_clk + xo_rst : OUT STD_LOGIC; + xo_rst_n : OUT STD_LOGIC; + + mm_clk : IN STD_LOGIC; -- 125 MHz from xo_clk PLL in SOPC system + mm_locked : IN STD_LOGIC; + mm_rst : OUT STD_LOGIC; + + dp_rst : OUT STD_LOGIC; + dp_clk : OUT STD_LOGIC; -- 200 MHz from CLK system clock + dp_phs_clk_vec : OUT STD_LOGIC_VECTOR(g_dp_phs_clk_vec_w-1 DOWNTO 0); -- divided and phase shifted from 200 MHz CLK system clock when a PLL is used + dp_pps : OUT STD_LOGIC; -- PPS in dp_clk domain + dp_rst_in : IN STD_LOGIC; -- externally wire OUT dp_rst to dp_rst_in to avoid delta cycle difference on dp_clk + dp_clk_in : IN STD_LOGIC; -- externally wire OUT dp_clk to dp_clk_in to avoid delta cycle difference on dp_clk (due to dp_clk <= i_dp_clk assignment) + + this_chip_id : OUT STD_LOGIC_VECTOR(c_unb1_board_nof_chip_w-1 DOWNTO 0); -- [2:0], so range 0-3 for FN and range 4-7 for BN + this_bck_id : OUT STD_LOGIC_VECTOR(c_unb1_board_nof_uniboard_w-1 DOWNTO 0); -- [1:0] used out of ID[7:3] to index boards 3..0 in subrack + + app_led_red : IN STD_LOGIC := '0'; + app_led_green : IN STD_LOGIC := '1'; + + -- PIOs + pout_debug_wave : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := (OTHERS=> '0'); + pout_wdi : IN STD_LOGIC; -- Toggled by unb_osy; can be overriden by reg_wdi. + pin_system_info : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + pin_pps : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for new designs best use reg_ppsh_mosi/miso + + -- Manual WDI override + reg_wdi_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_wdi_miso : OUT t_mem_miso; + + -- REMU + reg_remu_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_remu_miso : OUT t_mem_miso; + + -- EPCS + epcs_clk : IN STD_LOGIC := '0'; + + -- EPCS read + reg_dpmm_data_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_dpmm_data_miso : OUT t_mem_miso; + reg_dpmm_ctrl_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_dpmm_ctrl_miso : OUT t_mem_miso; + + -- EPCS write + reg_mmdp_data_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_mmdp_data_miso : OUT t_mem_miso; + reg_mmdp_ctrl_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_mmdp_ctrl_miso : OUT t_mem_miso; + + -- EPCS status/control + reg_epcs_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_epcs_miso : OUT t_mem_miso; + + -- MM buses to/from mms_unb1_board_system_info + reg_unb_system_info_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_unb_system_info_miso : OUT t_mem_miso; + + rom_unb_system_info_mosi : IN t_mem_mosi := c_mem_mosi_rst; + rom_unb_system_info_miso : OUT t_mem_miso; + + -- UniBoard I2C sensors + reg_unb_sens_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_unb_sens_miso : OUT t_mem_miso; + + -- PPSH + reg_ppsh_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_ppsh_miso : OUT t_mem_miso; + + -- eth1g control&monitoring + eth1g_tse_clk : IN STD_LOGIC; + eth1g_mm_rst : IN STD_LOGIC; + eth1g_tse_mosi : IN t_mem_mosi; -- ETH TSE MAC registers + eth1g_tse_miso : OUT t_mem_miso; + eth1g_reg_mosi : IN t_mem_mosi; -- ETH control and status registers + eth1g_reg_miso : OUT t_mem_miso; + eth1g_reg_interrupt : OUT STD_LOGIC; -- Interrupt + eth1g_ram_mosi : IN t_mem_mosi; -- ETH rx frame and tx frame memory + eth1g_ram_miso : OUT t_mem_miso; + + -- eth1g UDP streaming ports + udp_tx_sosi_arr : IN t_dp_sosi_arr(g_udp_offload_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + udp_tx_siso_arr : OUT t_dp_siso_arr(g_udp_offload_nof_streams-1 DOWNTO 0); + udp_rx_sosi_arr : OUT t_dp_sosi_arr(g_udp_offload_nof_streams-1 DOWNTO 0); + udp_rx_siso_arr : IN t_dp_siso_arr(g_udp_offload_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); + + -- + -- >>> Ctrl FPGA pins + -- + -- GENERAL + CLK : IN STD_LOGIC; -- System Clock + PPS : IN STD_LOGIC; -- System Sync + WDI : OUT STD_LOGIC; -- Watchdog Clear + INTA : INOUT STD_LOGIC; -- FPGA interconnect line + INTB : INOUT STD_LOGIC; -- FPGA interconnect line + + -- Others + VERSION : IN STD_LOGIC_VECTOR(g_aux.version_w-1 DOWNTO 0); + ID : IN STD_LOGIC_VECTOR(g_aux.id_w-1 DOWNTO 0); + TESTIO : INOUT STD_LOGIC_VECTOR(g_aux.testio_w-1 DOWNTO 0); + + -- I2C Interface to Sensors + sens_sc : INOUT STD_LOGIC := '1'; + sens_sd : INOUT STD_LOGIC := '1'; + + -- 1GbE Control Interface + ETH_clk : IN STD_LOGIC; + ETH_SGIN : IN STD_LOGIC; + ETH_SGOUT : OUT STD_LOGIC + ); +END ctrl_unb1_board; + + +ARCHITECTURE str OF ctrl_unb1_board IS + + + -- g_sel=0 for clk200_pll.vhd : used when ADUH is not used so g_dp_phs_clk_vec_w = g_nof_dp_phs_clk = 0 + -- g_sel=1 for clk200_pll_p6.vhd : used when ADUH is used so g_dp_phs_clk_vec_w = g_nof_dp_phs_clk > 0 + CONSTANT c_dp_clk_pll_sel : NATURAL := sel_a_b(g_dp_phs_clk_vec_w=0, 0, 1); + + -- Define c_dp_clk*_phase dependend on g_dp_phs_clk_vec_w in equal steps from 0 to 90 degrees of 200 MHz dp_clk. + -- g_dp_clk_vec_w = g_nof_dp_phs_clk = 0 1 2 3 4 5 6 + CONSTANT c_dp_clk1_phase : STRING := sel_n(g_dp_phs_clk_vec_w, "0", "0", "0", "0", "0", "0", "0"); -- degrees phase shifted PLL c1 output clock = dp_phs_clk_vec(0) + CONSTANT c_dp_clk2_phase : STRING := sel_n(g_dp_phs_clk_vec_w, "0", "0", "625", "313", "313", "156", "156"); -- degrees phase shifted PLL c2 output clock = dp_phs_clk_vec(1) + CONSTANT c_dp_clk3_phase : STRING := sel_n(g_dp_phs_clk_vec_w, "0", "0", "0", "781", "625", "313", "313"); -- degrees phase shifted PLL c3 output clock = dp_phs_clk_vec(2) + CONSTANT c_dp_clk4_phase : STRING := sel_n(g_dp_phs_clk_vec_w, "0", "0", "0", "0", "938", "469", "469"); -- degrees phase shifted PLL c4 output clock = dp_phs_clk_vec(3) + CONSTANT c_dp_clk5_phase : STRING := sel_n(g_dp_phs_clk_vec_w, "0", "0", "0", "0", "0", "625", "625"); -- degrees phase shifted PLL c5 output clock = dp_phs_clk_vec(4) + CONSTANT c_dp_clk6_phase : STRING := sel_n(g_dp_phs_clk_vec_w, "0", "0", "0", "0", "0", "0", "938"); -- degrees phase shifted PLL c6 output clock = dp_phs_clk_vec(5) + + -- Clock and reset + SIGNAL i_xo_clk : STD_LOGIC; + SIGNAL i_xo_rst : STD_LOGIC; + SIGNAL i_xo_rst_n : STD_LOGIC; + SIGNAL i_mm_rst : STD_LOGIC; + SIGNAL mm_wdi : STD_LOGIC; + SIGNAL eth1g_st_clk : STD_LOGIC; + SIGNAL eth1g_st_rst : STD_LOGIC; + + SIGNAL ext_clk : STD_LOGIC; + SIGNAL ext_pps : STD_LOGIC; + SIGNAL dp_dis : STD_LOGIC; + + SIGNAL node_ctrl_dp_clk_in : STD_LOGIC := '0'; + SIGNAL node_ctrl_dp_rst_out : STD_LOGIC; + + SIGNAL mm_pulse_ms : STD_LOGIC; + SIGNAL mm_pulse_s : STD_LOGIC; + SIGNAL mm_board_sens_start : STD_LOGIC; + + SIGNAL led_toggle : STD_LOGIC; + SIGNAL led_toggle_red : STD_LOGIC; + SIGNAL led_toggle_green : STD_LOGIC; + + -- eth1g + SIGNAL eth1g_led : t_tech_tse_led; + + -- Manual WDI override + SIGNAL wdi_override : STD_LOGIC; + + -- Temperature alarm (temp > g_fpga_temp_high) + SIGNAL temp_alarm : STD_LOGIC; + + -- UDP offload I/O + SIGNAL eth1g_udp_tx_sosi_arr : t_dp_sosi_arr(c_eth_nof_udp_ports-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + SIGNAL eth1g_udp_tx_siso_arr : t_dp_siso_arr(c_eth_nof_udp_ports-1 DOWNTO 0); + SIGNAL eth1g_udp_rx_sosi_arr : t_dp_sosi_arr(c_eth_nof_udp_ports-1 DOWNTO 0); + SIGNAL eth1g_udp_rx_siso_arr : t_dp_siso_arr(c_eth_nof_udp_ports-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); + +BEGIN + + xo_clk <= i_xo_clk; + xo_rst <= i_xo_rst; + xo_rst_n <= i_xo_rst_n; + mm_rst <= i_mm_rst; + + ----------------------------------------------------------------------------- + -- Node set up + ----------------------------------------------------------------------------- + + -- xo_rst output for SOPC's altpll0 instance + i_xo_rst <= NOT i_xo_rst_n; + + -- Default leave unused INOUT tri-state + INTA <= 'Z'; + INTB <= 'Z'; + + TESTIO <= (OTHERS=>'Z'); -- Leave unused INOUT tri-state + + -- Clock and reset + i_xo_clk <= ETH_clk; -- use the 25 MHz from the ETH_clk pin as xo_clk + ext_clk <= CLK; -- use the external 200 MHz CLK as ext_clk + ext_pps <= PPS; -- use more special name for PPS pin signal to ease searching for it in editor + + dp_dis <= i_mm_rst; -- could use software control for this instead + + gen_pll: IF g_dp_clk_use_pll = TRUE GENERATE + u_unb1_board_clk200_pll : ENTITY work.unb1_board_clk200_pll + GENERIC MAP ( + g_technology => g_technology, + g_sel => c_dp_clk_pll_sel, + g_clk200_phase_shift => g_dp_clk_phase, + g_clk_vec_w => g_dp_phs_clk_vec_w, + g_clk1_phase_shift => c_dp_clk1_phase, -- dp_phs_clk_vec(0) + g_clk2_phase_shift => c_dp_clk2_phase, -- dp_phs_clk_vec(1) + g_clk3_phase_shift => c_dp_clk3_phase, -- dp_phs_clk_vec(2) + g_clk4_phase_shift => c_dp_clk4_phase, -- dp_phs_clk_vec(3) + g_clk5_phase_shift => c_dp_clk5_phase, -- dp_phs_clk_vec(4) + g_clk6_phase_shift => c_dp_clk6_phase, -- dp_phs_clk_vec(5) + g_clk1_divide_by => g_dp_phs_clk_divide_by, + g_clk2_divide_by => g_dp_phs_clk_divide_by, + g_clk3_divide_by => g_dp_phs_clk_divide_by, + g_clk4_divide_by => g_dp_phs_clk_divide_by, + g_clk5_divide_by => g_dp_phs_clk_divide_by, + g_clk6_divide_by => g_dp_phs_clk_divide_by + ) + PORT MAP ( + arst => dp_dis, + clk200 => ext_clk, + st_clk200 => dp_clk, -- = c0 + st_rst200 => dp_rst, + st_clk_vec => dp_phs_clk_vec -- PLL c6-c1 + ); + END GENERATE; + + no_pll: IF g_dp_clk_use_pll = FALSE GENERATE + dp_rst <= node_ctrl_dp_rst_out; + node_ctrl_dp_clk_in <= dp_clk_in; + END GENERATE; + + u_unb1_board_node_ctrl : ENTITY work.unb1_board_node_ctrl + GENERIC MAP ( + g_pulse_us => g_mm_clk_freq / (10**6) -- nof system clock cycles to get us period, equal to system clock frequency / 10**6 + ) + PORT MAP ( + xo_clk => i_xo_clk, + xo_rst_n => i_xo_rst_n, + sys_clk => mm_clk, + sys_locked => mm_locked, + sys_rst => i_mm_rst, + cal_clk => '0', + cal_rst => OPEN, + st_clk => node_ctrl_dp_clk_in, + st_rst => node_ctrl_dp_rst_out, + wdi_in => pout_wdi, + wdi_out => mm_wdi, -- actively toggle the WDI via pout_wdi from software with toggle extend to allow software reload + pulse_us => OPEN, + pulse_ms => mm_pulse_ms, + pulse_s => mm_pulse_s -- could be used to toggle a LED + ); + + -- System info + cs_sim <= is_true(g_sim); + + u_mms_unb1_board_system_info : ENTITY work.mms_unb1_board_system_info + GENERIC MAP ( + g_sim => g_sim, + g_design_name => g_design_name, + g_use_phy => g_use_phy, + g_fw_version => g_fw_version, + g_stamp_date => g_stamp_date, + g_stamp_time => g_stamp_time, + g_stamp_svn => g_stamp_svn, + g_design_note => g_design_note + ) + PORT MAP ( + mm_clk => mm_clk, + mm_rst => i_mm_rst, + + hw_version => VERSION, + id => ID, + + info => pin_system_info, + + reg_mosi => reg_unb_system_info_mosi, + reg_miso => reg_unb_system_info_miso, + + rom_mosi => rom_unb_system_info_mosi, + rom_miso => rom_unb_system_info_miso, + + chip_id => this_chip_id, + bck_id => this_bck_id + ); + + + ----------------------------------------------------------------------------- + -- Red LED control + ----------------------------------------------------------------------------- + + gen_app_led_red: IF g_app_led_red = TRUE GENERATE + -- Let external app control the LED via the app_led_red input + TESTIO(c_unb1_board_testio_led_red) <= app_led_red; + END GENERATE; + + no_app_led_red: IF g_app_led_red = FALSE GENERATE + gen_dbg_led_red: IF g_dbg_led_red = TRUE GENERATE + TESTIO(c_unb1_board_testio_led_red) <= pout_debug_wave(pout_debug_wave'HIGH); -- [31] + END GENERATE; + + gen_toggle_led_red: IF g_dbg_led_red = FALSE GENERATE + TESTIO(c_unb1_board_testio_led_red) <= led_toggle_red; + END GENERATE; + END GENERATE; + + + ----------------------------------------------------------------------------- + -- Green LED control + ----------------------------------------------------------------------------- + + gen_app_led_green: IF g_app_led_green = TRUE GENERATE + -- Let external app control the LED via the app_led_green input + TESTIO(c_unb1_board_testio_led_green) <= app_led_green; + END GENERATE; + + no_app_led_green: IF g_app_led_green = FALSE GENERATE + gen_dbg_led_green: IF g_dbg_led_green = TRUE GENERATE + TESTIO(c_unb1_board_testio_led_green) <= pout_debug_wave(pout_debug_wave'HIGH-1); -- [30] + END GENERATE; + + gen_toggle_led_green: IF g_dbg_led_green = FALSE GENERATE + TESTIO(c_unb1_board_testio_led_green) <= led_toggle_green; + END GENERATE; + END GENERATE; + + + ------------------------------------------------------------------------------ + -- Toggle red LED when unb1_factory is running, green LED for other designs. + ------------------------------------------------------------------------------ + led_toggle_red <= sel_a_b(g_design_name="unb1_factory", led_toggle, '0'); + led_toggle_green <= sel_a_b(g_design_name/="unb1_factory", led_toggle, '0'); + + u_toggle : ENTITY common_lib.common_toggle + PORT MAP ( + rst => i_mm_rst, + clk => mm_clk, + in_dat => mm_pulse_s, + out_dat => led_toggle + ); + + + ------------------------------------------------------------------------------ + -- WDI override + ------------------------------------------------------------------------------ + -- Actively reset watchdog from software when used, else disable watchdog by leaving the WDI at tri-state level. + -- A high temp_alarm will keep WDI asserted, causing the watch dog to reset the FPGA. + -- A third option is to override the WDI manually using the output of a dedicated reg_wdi. + WDI <= sel_a_b(g_use_phy.wdi, mm_wdi OR temp_alarm OR wdi_override, 'Z'); + + u_unb1_board_wdi_reg : ENTITY work.unb1_board_wdi_reg + PORT MAP ( + mm_rst => i_mm_rst, + mm_clk => mm_clk, + + sla_in => reg_wdi_mosi, + sla_out => reg_wdi_miso, + + wdi_override => wdi_override + ); + + + ------------------------------------------------------------------------------ + -- Remote upgrade + ------------------------------------------------------------------------------ + -- Every design instantiates an mms_remu instance + MM status & control ports. + -- So there is full control over the memory mapped registers to set start address of the flash + -- and reconfigure from that address. + u_mms_remu: ENTITY remu_lib.mms_remu + PORT MAP ( + mm_rst => i_mm_rst, + mm_clk => mm_clk, + + epcs_clk => epcs_clk, + + remu_mosi => reg_remu_mosi, + remu_miso => reg_remu_miso + ); + + ----------------------------------------------------------------------------- + -- EPCS + ----------------------------------------------------------------------------- + u_mms_epcs: ENTITY epcs_lib.mms_epcs + PORT MAP ( + mm_rst => i_mm_rst, + mm_clk => mm_clk, + + epcs_clk => epcs_clk, + + epcs_mosi => reg_epcs_mosi, + epcs_miso => reg_epcs_miso, + + dpmm_ctrl_mosi => reg_dpmm_ctrl_mosi, + dpmm_ctrl_miso => reg_dpmm_ctrl_miso, + + dpmm_data_mosi => reg_dpmm_data_mosi, + dpmm_data_miso => reg_dpmm_data_miso, + + mmdp_ctrl_mosi => reg_mmdp_ctrl_mosi, + mmdp_ctrl_miso => reg_mmdp_ctrl_miso, + + mmdp_data_mosi => reg_mmdp_data_mosi, + mmdp_data_miso => reg_mmdp_data_miso + ); + + ------------------------------------------------------------------------------ + -- PPS input + ------------------------------------------------------------------------------ + + u_mms_ppsh : ENTITY ppsh_lib.mms_ppsh + GENERIC MAP ( + g_st_clk_freq => g_dp_clk_freq + ) + PORT MAP ( + -- Clocks and reset + mm_rst => i_mm_rst, + mm_clk => mm_clk, + st_rst => dp_rst_in, + st_clk => dp_clk_in, + pps_ext => ext_pps, -- with unknown but constant phase to st_clk + + -- Memory-mapped clock domain + reg_mosi => reg_ppsh_mosi, + reg_miso => reg_ppsh_miso, + + -- Old PIO support (for backwards compatibility with pin_pps on ctrl_unb1_board) + pin_pps => pin_pps, + + -- Streaming clock domain + pps_sys => dp_pps + ); + + + ------------------------------------------------------------------------------ + -- I2C control for UniBoard sensors + ------------------------------------------------------------------------------ + + mm_board_sens_start <= mm_pulse_s WHEN g_sim=FALSE ELSE mm_pulse_ms; -- speed up in simulation + + u_mms_unb1_board_sens : ENTITY work.mms_unb1_board_sens + GENERIC MAP ( + g_sim => g_sim, + g_clk_freq => g_mm_clk_freq, + g_temp_high => g_fpga_temp_high + ) + PORT MAP ( + -- Clocks and reset + mm_rst => i_mm_rst, + mm_clk => mm_clk, + mm_start => mm_board_sens_start, + + -- Memory-mapped clock domain + reg_mosi => reg_unb_sens_mosi, + reg_miso => reg_unb_sens_miso, + + -- i2c bus + scl => sens_sc, + sda => sens_sd, + + -- Temperature alarm + temp_alarm => temp_alarm + ); + + + ------------------------------------------------------------------------------ + -- Ethernet 1GbE + ------------------------------------------------------------------------------ + + no_eth1g : IF g_use_phy.eth1g=0 GENERATE + eth1g_reg_interrupt <= '0'; + eth1g_tse_miso <= c_mem_miso_rst; + eth1g_reg_miso <= c_mem_miso_rst; + eth1g_ram_miso <= c_mem_miso_rst; + END GENERATE; + + use_eth1g : IF g_use_phy.eth1g/=0 GENERATE + + gen_same_clk: IF g_udp_offload=TRUE GENERATE + + eth1g_st_clk <= dp_clk_in; + eth1g_st_rst <= dp_rst_in; + + gen_offload_io: FOR i IN 0 TO g_udp_offload_nof_streams-1 GENERATE + eth1g_udp_tx_sosi_arr(i) <= udp_tx_sosi_arr(i); + udp_tx_siso_arr(i) <= eth1g_udp_tx_siso_arr(i); + + udp_rx_sosi_arr(i) <= eth1g_udp_rx_sosi_arr(i); + eth1g_udp_rx_siso_arr(i) <= udp_rx_siso_arr(i); + END GENERATE; + + END GENERATE; + + gen_separate_clk: IF g_udp_offload=FALSE GENERATE + eth1g_st_clk <= mm_clk; + eth1g_st_rst <= eth1g_mm_rst; + END GENERATE; + + u_mac : ENTITY eth_lib.eth + GENERIC MAP ( + g_technology => g_technology, + g_cross_clock_domain => g_udp_offload + ) + PORT MAP ( + -- Clocks and reset + mm_rst => eth1g_mm_rst, -- use reset from SOPC + mm_clk => mm_clk, -- use mm_clk direct + eth_clk => eth1g_tse_clk, -- use the dedicated 125 MHz tse_clock, independent of the mm_clk + st_rst => eth1g_st_rst, + st_clk => eth1g_st_clk, + + -- UDP transmit interface + udp_tx_snk_in_arr => eth1g_udp_tx_sosi_arr, + udp_tx_snk_out_arr => eth1g_udp_tx_siso_arr, + -- UDP receive interface + udp_rx_src_in_arr => eth1g_udp_rx_siso_arr, + udp_rx_src_out_arr => eth1g_udp_rx_sosi_arr, + + -- Memory Mapped Slaves + tse_sla_in => eth1g_tse_mosi, + tse_sla_out => eth1g_tse_miso, + reg_sla_in => eth1g_reg_mosi, + reg_sla_out => eth1g_reg_miso, + reg_sla_interrupt => eth1g_reg_interrupt, + ram_sla_in => eth1g_ram_mosi, + ram_sla_out => eth1g_ram_miso, + + -- PHY interface + eth_txp => ETH_SGOUT, + eth_rxp => ETH_SGIN, + + -- LED interface + tse_led => eth1g_led + ); + END GENERATE; + +END str; -- GitLab